https://github.com/xakep8 updated https://github.com/llvm/llvm-project/pull/226546
>From 26b71d1bc55b76962f36bb85f8473e5ac8e17342 Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Fri, 25 Sep 2026 22:45:22 +0530 Subject: [PATCH] [CIR] Added Vector Reduce Op Added cir.vec.reduce for vector reduction builtins supporting integer, floating-point, bitwise and min/max reductions. Used the operation for generic and x86 reduction builtins and preserved expression FP options and merged builtin-required reassoc and nnan flags. Added CIR, verifier, lowering, fixed and scalable vector, boolean, FP16 and fast-math regression tests. --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 63 ++++++++++++ clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 90 +++++++++-------- clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 44 +++++---- clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 23 +++++ clang/lib/CIR/CodeGen/CIRGenFunction.h | 5 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 71 +++++++++++++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 68 +++++++++++++ .../CodeGenBuiltins/X86/avx512-reduceIntrin.c | 27 +++-- .../X86/avx512-reduceMinMaxIntrin.c | 27 +++-- .../CodeGenBuiltins/X86/avx512fp16-builtins.c | 16 +-- .../X86/avx512vlfp16-builtins.c | 33 +++---- .../builtin-reduce-arithmetic-sve.c | 27 +++-- .../builtin-reduce-arithmetic.c | 58 +++++++---- .../CodeGenBuiltins/builtin-reduce-bitwise.c | 20 +++- .../builtin-reduce-fast-math.c | 99 +++++++++++++++++++ clang/test/CIR/IR/invalid-vector-reduce.cir | 78 +++++++++++++++ clang/test/CIR/IR/vector.cir | 43 ++++++++ clang/test/CIR/Lowering/vector-reduce.cir | 50 ++++++++++ 18 files changed, 707 insertions(+), 135 deletions(-) create mode 100644 clang/test/CIR/CodeGenBuiltins/builtin-reduce-fast-math.c create mode 100644 clang/test/CIR/IR/invalid-vector-reduce.cir create mode 100644 clang/test/CIR/Lowering/vector-reduce.cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index e450423c12ce247..a193c4d12a95fe9 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -6169,6 +6169,69 @@ def CIR_VecExtractOp : CIR_Op<"vec.extract", [ let hasFolder = 1; } +//===----------------------------------------------------------------------===// +// VecReduceOp +//===----------------------------------------------------------------------===// + +def CIR_VecReduceKind : CIR_I32Enum< + "VecReduceKind", "vector reduction operation kind", [ + I32EnumCase<"Add", 0, "add">, + I32EnumCase<"Mul", 1, "mul">, + I32EnumCase<"And", 2, "and">, + I32EnumCase<"Or", 3, "or">, + I32EnumCase<"Xor", 4, "xor">, + I32EnumCase<"SMax", 5, "smax">, + I32EnumCase<"SMin", 6, "smin">, + I32EnumCase<"UMax", 7, "umax">, + I32EnumCase<"UMin", 8, "umin">, + I32EnumCase<"FAdd", 9, "fadd">, + I32EnumCase<"FMul", 10, "fmul">, + I32EnumCase<"FMax", 11, "fmax">, + I32EnumCase<"FMin", 12, "fmin"> +]>; + +def CIR_VecReduceKindAttr + : CIR_EnumAttr<CIR_VecReduceKind, "vec_reduce">; + +def CIR_VecReduceOp : CIR_Op<"vec.reduce", [ + Pure, + TypesMatchWith<"type of 'result' matches element type of 'input'", + "input", "result", + "mlir::cast<cir::VectorType>($_self).getElementType()"> +]> { + let summary = "Reduce a vector to a scalar"; + let description = [{ + The `cir.vec.reduce` operation combines the elements of a vector using the + specified reduction kind and returns a scalar of the vector element type. + Floating-point addition and multiplication require an accumulator value. + + Examples: + + ``` + %sum = cir.vec.reduce(add, %vec) : (!cir.vector<4 x !s32i>) -> !s32i + %fsum = cir.vec.reduce(fadd, %fvec, %start) : + (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float + <fastmath_flags = [reassoc]> + ``` + }]; + + let arguments = (ins + CIR_VectorType:$input, + Optional<CIR_VectorElementType>:$accumulator, + CIR_VecReduceKindAttr:$kind, + OptionalAttr<CIR_FastMathFlagsAttr>:$fastmath_flags + ); + + let results = (outs CIR_VectorElementType:$result); + + let assemblyFormat = [{ + `(` enum($kind) `,` $input (`,` $accumulator^)? `)` `:` + functional-type(operands, results) prop-dict attr-dict + }]; + + let hasVerifier = 1; +} + //===----------------------------------------------------------------------===// // VecCmpOp //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 9203cc0b9f7220f..4ef1bdb757a292b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -2193,7 +2193,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, return errorBuiltinNYI(*this, e, builtinID); case Builtin::BI__builtin_reduce_max: case Builtin::BI__builtin_reduce_min: { - auto getIntrinsicName = [this, builtinIDIfNoAsmLabel](QualType type) { + CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(*this, e); + auto getReductionKind = [this, builtinIDIfNoAsmLabel](QualType type) { if (const auto *vecTy = type->getAs<VectorType>()) type = vecTy->getElementType(); else if (type->isSizelessVectorType()) @@ -2201,52 +2202,64 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, if (builtinIDIfNoAsmLabel == Builtin::BI__builtin_reduce_max) { if (type->isSignedIntegerType()) - return "vector.reduce.smax"; + return cir::VecReduceKind::SMax; if (type->isUnsignedIntegerType()) - return "vector.reduce.umax"; + return cir::VecReduceKind::UMax; assert(type->isFloatingType() && "must have a float here"); - return "vector.reduce.fmax"; + return cir::VecReduceKind::FMax; } if (type->isSignedIntegerType()) - return "vector.reduce.smin"; + return cir::VecReduceKind::SMin; if (type->isUnsignedIntegerType()) - return "vector.reduce.umin"; + return cir::VecReduceKind::UMin; assert(type->isFloatingType() && "must have a float here"); - return "vector.reduce.fmin"; + return cir::VecReduceKind::FMin; }; - return emitBuiltinWithOneOverloadedType<1>( - e, getIntrinsicName(e->getArg(0)->getType()), - cast<cir::VectorType>(convertType(e->getArg(0)->getType())) - .getElementType()); + mlir::Value input = emitScalarExpr(e->getArg(0)); + cir::VecReduceKind kind = getReductionKind(e->getArg(0)->getType()); + cir::FastMathFlagsAttr fastMath; + if (kind == cir::VecReduceKind::FMax || kind == cir::VecReduceKind::FMin) + fastMath = getFastMathFlagsAttr(); + auto reduction = cir::VecReduceOp::create( + builder, getLoc(e->getExprLoc()), input, mlir::Value{}, kind, fastMath); + return RValue::get(reduction.getResult()); } case Builtin::BI__builtin_reduce_add: - return emitBuiltinWithOneOverloadedType<1>( - e, "vector.reduce.add", - cast<cir::VectorType>(convertType(e->getArg(0)->getType())) - .getElementType()); case Builtin::BI__builtin_reduce_mul: - return emitBuiltinWithOneOverloadedType<1>( - e, "vector.reduce.mul", - cast<cir::VectorType>(convertType(e->getArg(0)->getType())) - .getElementType()); case Builtin::BI__builtin_reduce_xor: - return emitBuiltinWithOneOverloadedType<1>( - e, "vector.reduce.xor", - cast<cir::VectorType>(convertType(e->getArg(0)->getType())) - .getElementType()); case Builtin::BI__builtin_reduce_or: - return emitBuiltinWithOneOverloadedType<1>( - e, "vector.reduce.or", - cast<cir::VectorType>(convertType(e->getArg(0)->getType())) - .getElementType()); - case Builtin::BI__builtin_reduce_and: - return emitBuiltinWithOneOverloadedType<1>( - e, "vector.reduce.and", - cast<cir::VectorType>(convertType(e->getArg(0)->getType())) - .getElementType()); + case Builtin::BI__builtin_reduce_and: { + cir::VecReduceKind kind; + switch (builtinIDIfNoAsmLabel) { + case Builtin::BI__builtin_reduce_add: + kind = cir::VecReduceKind::Add; + break; + case Builtin::BI__builtin_reduce_mul: + kind = cir::VecReduceKind::Mul; + break; + case Builtin::BI__builtin_reduce_xor: + kind = cir::VecReduceKind::Xor; + break; + case Builtin::BI__builtin_reduce_or: + kind = cir::VecReduceKind::Or; + break; + case Builtin::BI__builtin_reduce_and: + kind = cir::VecReduceKind::And; + break; + default: + llvm_unreachable("unexpected vector reduction builtin"); + } + + mlir::Value input = emitScalarExpr(e->getArg(0)); + auto reduction = + cir::VecReduceOp::create(builder, getLoc(e->getExprLoc()), input, + mlir::Value{}, kind, cir::FastMathFlagsAttr{}); + return RValue::get(reduction.getResult()); + } case Builtin::BI__builtin_reduce_assoc_fadd: case Builtin::BI__builtin_reduce_in_order_fadd: { + CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(*this, e); bool isAssociative = builtinIDIfNoAsmLabel == Builtin::BI__builtin_reduce_assoc_fadd; @@ -2273,15 +2286,12 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, /*Negative=*/true))); } - SmallVector<mlir::Value, 2> args = {startValue, vector}; - cir::FastMathFlagsAttr fastMath; - if (isAssociative) - fastMath = cir::FastMathFlagsAttr::get(&getMLIRContext(), - cir::FastMathFlags::reassoc); + cir::FastMathFlagsAttr fastMath = getFastMathFlagsAttr( + isAssociative ? cir::FastMathFlags::reassoc : cir::FastMathFlags::none); - mlir::Value result = builder.emitIntrinsicCallOp(loc, "vector.reduce.fadd", - scalarTy, fastMath, args); - return RValue::get(result); + auto reduction = cir::VecReduceOp::create( + builder, loc, vector, startValue, cir::VecReduceKind::FAdd, fastMath); + return RValue::get(reduction.getResult()); } case Builtin::BI__builtin_reduce_maximum: case Builtin::BI__builtin_reduce_minimum: diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index bc376e4aaab616d..0b5545fdf13e869 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -2425,42 +2425,50 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) { case X86::BI__builtin_ia32_reduce_fadd_ph512: case X86::BI__builtin_ia32_reduce_fadd_ph256: case X86::BI__builtin_ia32_reduce_fadd_ph128: { - assert(!cir::MissingFeatures::fastMathFlags()); - return builder.emitIntrinsicCallOp(getLoc(expr->getExprLoc()), - "vector.reduce.fadd", ops[0].getType(), - mlir::ValueRange{ops[0], ops[1]}); + CIRGenFPOptionsRAII FPOptsRAII(*this, expr); + cir::FastMathFlagsAttr fastMath = + getFastMathFlagsAttr(cir::FastMathFlags::reassoc); + return cir::VecReduceOp::create(builder, getLoc(expr->getExprLoc()), ops[1], + ops[0], cir::VecReduceKind::FAdd, fastMath) + .getResult(); } case X86::BI__builtin_ia32_reduce_fmul_pd512: case X86::BI__builtin_ia32_reduce_fmul_ps512: case X86::BI__builtin_ia32_reduce_fmul_ph512: case X86::BI__builtin_ia32_reduce_fmul_ph256: case X86::BI__builtin_ia32_reduce_fmul_ph128: { - assert(!cir::MissingFeatures::fastMathFlags()); - return builder.emitIntrinsicCallOp(getLoc(expr->getExprLoc()), - "vector.reduce.fmul", ops[0].getType(), - mlir::ValueRange{ops[0], ops[1]}); + CIRGenFPOptionsRAII FPOptsRAII(*this, expr); + cir::FastMathFlagsAttr fastMath = + getFastMathFlagsAttr(cir::FastMathFlags::reassoc); + return cir::VecReduceOp::create(builder, getLoc(expr->getExprLoc()), ops[1], + ops[0], cir::VecReduceKind::FMul, fastMath) + .getResult(); } case X86::BI__builtin_ia32_reduce_fmax_pd512: case X86::BI__builtin_ia32_reduce_fmax_ps512: case X86::BI__builtin_ia32_reduce_fmax_ph512: case X86::BI__builtin_ia32_reduce_fmax_ph256: case X86::BI__builtin_ia32_reduce_fmax_ph128: { - assert(!cir::MissingFeatures::fastMathFlags()); - cir::VectorType vecTy = cast<cir::VectorType>(ops[0].getType()); - return builder.emitIntrinsicCallOp( - getLoc(expr->getExprLoc()), "vector.reduce.fmax", - vecTy.getElementType(), mlir::ValueRange{ops[0]}); + CIRGenFPOptionsRAII FPOptsRAII(*this, expr); + cir::FastMathFlagsAttr fastMath = + getFastMathFlagsAttr(cir::FastMathFlags::nnan); + return cir::VecReduceOp::create(builder, getLoc(expr->getExprLoc()), ops[0], + mlir::Value{}, cir::VecReduceKind::FMax, + fastMath) + .getResult(); } case X86::BI__builtin_ia32_reduce_fmin_pd512: case X86::BI__builtin_ia32_reduce_fmin_ps512: case X86::BI__builtin_ia32_reduce_fmin_ph512: case X86::BI__builtin_ia32_reduce_fmin_ph256: case X86::BI__builtin_ia32_reduce_fmin_ph128: { - assert(!cir::MissingFeatures::fastMathFlags()); - cir::VectorType vecTy = cast<cir::VectorType>(ops[0].getType()); - return builder.emitIntrinsicCallOp( - getLoc(expr->getExprLoc()), "vector.reduce.fmin", - vecTy.getElementType(), mlir::ValueRange{ops[0]}); + CIRGenFPOptionsRAII FPOptsRAII(*this, expr); + cir::FastMathFlagsAttr fastMath = + getFastMathFlagsAttr(cir::FastMathFlags::nnan); + return cir::VecReduceOp::create(builder, getLoc(expr->getExprLoc()), ops[0], + mlir::Value{}, cir::VecReduceKind::FMin, + fastMath) + .getResult(); } case X86::BI__builtin_ia32_rdrand16_step: case X86::BI__builtin_ia32_rdrand32_step: diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index 382a0008113e225..4809e7680d303eb 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -1471,6 +1471,29 @@ CIRGenFunction::CIRGenFPOptionsRAII::~CIRGenFPOptionsRAII() { cgf.builder.setDefaultConstrainedRounding(oldRounding); } +cir::FastMathFlagsAttr +CIRGenFunction::getFastMathFlagsAttr(cir::FastMathFlags additionalFlags) { + cir::FastMathFlags flags = additionalFlags; + if (curFPFeatures.getAllowFPReassociate()) + flags |= cir::FastMathFlags::reassoc; + if (curFPFeatures.getNoHonorNaNs()) + flags |= cir::FastMathFlags::nnan; + if (curFPFeatures.getNoHonorInfs()) + flags |= cir::FastMathFlags::ninf; + if (curFPFeatures.getNoSignedZero()) + flags |= cir::FastMathFlags::nsz; + if (curFPFeatures.getAllowReciprocal()) + flags |= cir::FastMathFlags::arcp; + if (curFPFeatures.getAllowApproxFunc()) + flags |= cir::FastMathFlags::afn; + if (curFPFeatures.allowFPContractAcrossStatement()) + flags |= cir::FastMathFlags::contract; + + if (flags == cir::FastMathFlags::none) + return {}; + return cir::FastMathFlagsAttr::get(&getMLIRContext(), flags); +} + // TODO(cir): should be shared with LLVM codegen. bool CIRGenFunction::shouldNullCheckClassCastValue(const CastExpr *ce) { const Expr *e = ce->getSubExpr(); diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index c6427d60a379268..3b6e7b0ccae93b6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -342,6 +342,11 @@ class CIRGenFunction : public CIRGenTypeCache { }; clang::FPOptions curFPFeatures; + /// Convert the active Clang floating-point options to CIR fast-math flags, + /// including any flags required by the operation itself. + cir::FastMathFlagsAttr getFastMathFlagsAttr( + cir::FastMathFlags additionalFlags = cir::FastMathFlags::none); + /// The symbol table maps a variable name to a value in the current scope. /// Entering a function creates a new scope, and the function arguments are /// added to the mapping. When the processing of a function is terminated, diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 15cebd358040e3f..07c2b2ef09ba1ca 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -4098,6 +4098,77 @@ OpFoldResult cir::VecExtractOp::fold(FoldAdaptor adaptor) { return elements[index]; } +//===----------------------------------------------------------------------===// +// VecReduceOp +//===----------------------------------------------------------------------===// + +LogicalResult cir::VecReduceOp::verify() { + mlir::Type elementTy = getInput().getType().getElementType(); + const bool hasAccumulator = static_cast<bool>(getAccumulator()); + const bool isFloatingPoint = cir::isAnyFloatingPointType(elementTy); + const bool isInteger = mlir::isa<cir::IntType>(elementTy); + const bool isIntegerOrBool = isInteger || mlir::isa<cir::BoolType>(elementTy); + + if (getAccumulator() && getAccumulator().getType() != elementTy) + return emitOpError() << "accumulator type " << getAccumulator().getType() + << " doesn't match vector element type " << elementTy; + + const bool requiresAccumulator = getKind() == cir::VecReduceKind::FAdd || + getKind() == cir::VecReduceKind::FMul; + if (hasAccumulator != requiresAccumulator) + return emitOpError() << (requiresAccumulator ? "requires" + : "does not accept") + << " an accumulator for " + << stringifyVecReduceKind(getKind()) << " reduction"; + + if (getFastmathFlagsAttr() && !isFloatingPoint) + return emitOpError() + << "fast-math flags are only valid for floating-point reductions"; + + switch (getKind()) { + case cir::VecReduceKind::Add: + case cir::VecReduceKind::Mul: + if (!isIntegerOrBool) + return emitOpError() << "requires an integer or boolean vector for " + << stringifyVecReduceKind(getKind()) << " reduction"; + break; + case cir::VecReduceKind::And: + case cir::VecReduceKind::Or: + case cir::VecReduceKind::Xor: + if (!isIntegerOrBool) + return emitOpError() << "requires an integer or boolean vector for " + << stringifyVecReduceKind(getKind()) << " reduction"; + break; + case cir::VecReduceKind::SMax: + case cir::VecReduceKind::SMin: { + auto intTy = mlir::dyn_cast<cir::IntType>(elementTy); + if (!intTy || !intTy.isSigned()) + return emitOpError() << "requires a signed integer vector for " + << stringifyVecReduceKind(getKind()) << " reduction"; + break; + } + case cir::VecReduceKind::UMax: + case cir::VecReduceKind::UMin: { + auto intTy = mlir::dyn_cast<cir::IntType>(elementTy); + if ((!intTy || !intTy.isUnsigned()) && !mlir::isa<cir::BoolType>(elementTy)) + return emitOpError() + << "requires an unsigned integer or boolean vector for " + << stringifyVecReduceKind(getKind()) << " reduction"; + break; + } + case cir::VecReduceKind::FAdd: + case cir::VecReduceKind::FMul: + case cir::VecReduceKind::FMax: + case cir::VecReduceKind::FMin: + if (!isFloatingPoint) + return emitOpError() << "requires a floating-point vector for " + << stringifyVecReduceKind(getKind()) << " reduction"; + break; + } + + return success(); +} + //===----------------------------------------------------------------------===// // CmpOp //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 8c6679c1c5c512c..7fd1ce78e549690 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -5076,6 +5076,74 @@ mlir::LogicalResult CIRToLLVMVecInsertOpLowering::matchAndRewrite( return mlir::success(); } +mlir::LogicalResult CIRToLLVMVecReduceOpLowering::matchAndRewrite( + cir::VecReduceOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + mlir::Type resultTy = getTypeConverter()->convertType(op.getType()); + mlir::LLVM::FastmathFlags fastmathFlags{}; + if (std::optional<cir::FastMathFlags> fastmath = op.getFastmathFlags()) + fastmathFlags = convertFastMathFlags(*fastmath); + + switch (op.getKind()) { + case cir::VecReduceKind::Add: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_add>( + op, resultTy, adaptor.getInput()); + break; + case cir::VecReduceKind::Mul: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_mul>( + op, resultTy, adaptor.getInput()); + break; + case cir::VecReduceKind::And: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_and>( + op, resultTy, adaptor.getInput()); + break; + case cir::VecReduceKind::Or: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_or>( + op, resultTy, adaptor.getInput()); + break; + case cir::VecReduceKind::Xor: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_xor>( + op, resultTy, adaptor.getInput()); + break; + case cir::VecReduceKind::SMax: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_smax>( + op, resultTy, adaptor.getInput()); + break; + case cir::VecReduceKind::SMin: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_smin>( + op, resultTy, adaptor.getInput()); + break; + case cir::VecReduceKind::UMax: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_umax>( + op, resultTy, adaptor.getInput()); + break; + case cir::VecReduceKind::UMin: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_umin>( + op, resultTy, adaptor.getInput()); + break; + case cir::VecReduceKind::FAdd: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_fadd>( + op, resultTy, adaptor.getAccumulator(), adaptor.getInput(), + fastmathFlags); + break; + case cir::VecReduceKind::FMul: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_fmul>( + op, resultTy, adaptor.getAccumulator(), adaptor.getInput(), + fastmathFlags); + break; + case cir::VecReduceKind::FMax: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_fmax>( + op, resultTy, adaptor.getInput(), fastmathFlags); + break; + case cir::VecReduceKind::FMin: + rewriter.replaceOpWithNewOp<mlir::LLVM::vector_reduce_fmin>( + op, resultTy, adaptor.getInput(), fastmathFlags); + break; + } + + return mlir::success(); +} + mlir::LogicalResult CIRToLLVMVecCmpOpLowering::matchAndRewrite( cir::VecCmpOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512-reduceIntrin.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512-reduceIntrin.c index acb6dca7a24f509..b9d2f20ee457315 100644 --- a/clang/test/CIR/CodeGenBuiltins/X86/avx512-reduceIntrin.c +++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512-reduceIntrin.c @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -x c -ffreestanding %s -O2 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -fclangir -emit-cir -o - -Wall -Werror | FileCheck %s --check-prefixes=CIR // RUN: %clang_cc1 -x c -ffreestanding %s -O2 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -fclangir -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=LLVM // RUN: %clang_cc1 -x c -ffreestanding %s -O2 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=OGCG +// RUN: %clang_cc1 -x c -ffreestanding %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -menable-no-infs -fclangir -emit-cir -o - -Wall -Werror | FileCheck %s --check-prefix=CIR-NINF +// RUN: %clang_cc1 -x c -ffreestanding %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -menable-no-infs -fclangir -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=LLVM-NINF +// RUN: %clang_cc1 -x c -ffreestanding %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -menable-no-infs -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=LLVM-NINF #include <immintrin.h> @@ -10,10 +13,14 @@ double test_mm512_reduce_add_pd(__m512d __W, double ExtraAddOp){ // CIR: cir.call @_mm512_reduce_add_pd(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<8 x !cir.double>{{.*}}) -> !cir.double // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_add_pd( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[R:.*]], %[[V:.*]] : (!cir.double{{.*}}, !cir.vector<8 x !cir.double>{{.*}}) -> !cir.double + // CIR: cir.vec.reduce(fadd, %[[V:.*]], %[[R:.*]]) : (!cir.vector<8 x !cir.double>, !cir.double) -> !cir.double <fastmath_flags = [reassoc]> + // CIR-NINF-LABEL: cir.func{{.*}} @_mm512_reduce_add_pd( + // CIR-NINF: cir.vec.reduce(fadd, {{.*}}) {{.*}} <fastmath_flags = [ninf, reassoc]> // LLVM-LABEL: test_mm512_reduce_add_pd - // LLVM: call double @llvm.vector.reduce.fadd.v8f64(double -0.000000e+00, <8 x double> %{{.*}}) + // LLVM: call reassoc double @llvm.vector.reduce.fadd.v8f64(double -0.000000e+00, <8 x double> %{{.*}}) + // LLVM-NINF-LABEL: define {{.*}} @test_mm512_reduce_add_pd( + // LLVM-NINF: call reassoc ninf {{.*}}double @llvm.vector.reduce.fadd.v8f64( // OGCG-LABEL: test_mm512_reduce_add_pd // OGCG-NOT: reassoc @@ -27,10 +34,14 @@ double test_mm512_reduce_mul_pd(__m512d __W, double ExtraMulOp){ // CIR: cir.call @_mm512_reduce_mul_pd(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<8 x !cir.double>{{.*}}) -> !cir.double // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_mul_pd( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmul" %[[R:.*]], %[[V:.*]] : (!cir.double{{.*}}, !cir.vector<8 x !cir.double>{{.*}}) -> !cir.double + // CIR: cir.vec.reduce(fmul, %[[V:.*]], %[[R:.*]]) : (!cir.vector<8 x !cir.double>, !cir.double) -> !cir.double <fastmath_flags = [reassoc]> + // CIR-NINF-LABEL: cir.func{{.*}} @_mm512_reduce_mul_pd( + // CIR-NINF: cir.vec.reduce(fmul, {{.*}}) {{.*}} <fastmath_flags = [ninf, reassoc]> // LLVM-LABEL: test_mm512_reduce_mul_pd - // LLVM: call double @llvm.vector.reduce.fmul.v8f64(double 1.000000e+00, <8 x double> %{{.*}}) + // LLVM: call reassoc double @llvm.vector.reduce.fmul.v8f64(double 1.000000e+00, <8 x double> %{{.*}}) + // LLVM-NINF-LABEL: define {{.*}} @test_mm512_reduce_mul_pd( + // LLVM-NINF: call reassoc ninf {{.*}}double @llvm.vector.reduce.fmul.v8f64( // OGCG-LABEL: test_mm512_reduce_mul_pd // OGCG-NOT: reassoc @@ -45,10 +56,10 @@ float test_mm512_reduce_add_ps(__m512 __W){ // CIR: cir.call @_mm512_reduce_add_ps(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<16 x !cir.float>{{.*}}) -> !cir.float // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_add_ps( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[R:.*]], %[[V:.*]] : (!cir.float{{.*}}, !cir.vector<16 x !cir.float>{{.*}}) -> !cir.float + // CIR: cir.vec.reduce(fadd, %[[V:.*]], %[[R:.*]]) : (!cir.vector<16 x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> // LLVM-LABEL: test_mm512_reduce_add_ps - // LLVM: call float @llvm.vector.reduce.fadd.v16f32(float -0.000000e+00, <16 x float> %{{.*}}) + // LLVM: call reassoc float @llvm.vector.reduce.fadd.v16f32(float -0.000000e+00, <16 x float> %{{.*}}) // OGCG-LABEL: test_mm512_reduce_add_ps // OGCG: call reassoc {{.*}}float @llvm.vector.reduce.fadd.v16f32(float -0.000000e+00, <16 x float> %{{.*}}) @@ -60,10 +71,10 @@ float test_mm512_reduce_mul_ps(__m512 __W){ // CIR: cir.call @_mm512_reduce_mul_ps(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<16 x !cir.float>{{.*}}) -> !cir.float // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_mul_ps( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmul" %[[R:.*]], %[[V:.*]] : (!cir.float{{.*}}, !cir.vector<16 x !cir.float>{{.*}}) -> !cir.float + // CIR: cir.vec.reduce(fmul, %[[V:.*]], %[[R:.*]]) : (!cir.vector<16 x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> // LLVM-LABEL: test_mm512_reduce_mul_ps - // LLVM: call float @llvm.vector.reduce.fmul.v16f32(float 1.000000e+00, <16 x float> %{{.*}}) + // LLVM: call reassoc float @llvm.vector.reduce.fmul.v16f32(float 1.000000e+00, <16 x float> %{{.*}}) // OGCG-LABEL: test_mm512_reduce_mul_ps // OGCG: call reassoc {{.*}}float @llvm.vector.reduce.fmul.v16f32(float 1.000000e+00, <16 x float> %{{.*}}) diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512-reduceMinMaxIntrin.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512-reduceMinMaxIntrin.c index eb60be24e9345ff..913162a33679435 100644 --- a/clang/test/CIR/CodeGenBuiltins/X86/avx512-reduceMinMaxIntrin.c +++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512-reduceMinMaxIntrin.c @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -x c -ffreestanding %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -fclangir -emit-cir -o - -Wall -Werror | FileCheck %s --check-prefixes=CIR // RUN: %clang_cc1 -x c -ffreestanding %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -fclangir -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=LLVM // RUN: %clang_cc1 -x c -ffreestanding %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=OGCG +// RUN: %clang_cc1 -x c -ffreestanding %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -menable-no-infs -fclangir -emit-cir -o - -Wall -Werror | FileCheck %s --check-prefix=CIR-NINF +// RUN: %clang_cc1 -x c -ffreestanding %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -menable-no-infs -fclangir -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=LLVM-NINF +// RUN: %clang_cc1 -x c -ffreestanding %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -menable-no-infs -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=LLVM-NINF #include <immintrin.h> @@ -9,10 +12,14 @@ double test_mm512_reduce_max_pd(__m512d __W, double ExtraAddOp){ // CIR: cir.call @_mm512_reduce_max_pd(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<8 x !cir.double>{{.*}}) -> !cir.double // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_max_pd( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmax" %[[V:.*]] : (!cir.vector<8 x !cir.double>{{.*}}) -> !cir.double + // CIR: cir.vec.reduce(fmax, %[[V:.*]]) : (!cir.vector<8 x !cir.double>) -> !cir.double <fastmath_flags = [nnan]> + // CIR-NINF-LABEL: cir.func{{.*}} @_mm512_reduce_max_pd( + // CIR-NINF: cir.vec.reduce(fmax, {{.*}}) {{.*}} <fastmath_flags = [nnan, ninf]> // LLVM-LABEL: test_mm512_reduce_max_pd - // LLVM: call double @llvm.vector.reduce.fmax.v8f64(<8 x double> %{{.*}}) + // LLVM: call nnan double @llvm.vector.reduce.fmax.v8f64(<8 x double> %{{.*}}) + // LLVM-NINF-LABEL: define {{.*}} @test_mm512_reduce_max_pd( + // LLVM-NINF: call nnan ninf {{.*}}double @llvm.vector.reduce.fmax.v8f64( // OGCG-LABEL: test_mm512_reduce_max_pd // OGCG-NOT: nnan @@ -26,10 +33,14 @@ double test_mm512_reduce_min_pd(__m512d __W, double ExtraMulOp){ // CIR: cir.call @_mm512_reduce_min_pd(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<8 x !cir.double>{{.*}}) -> !cir.double // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_min_pd( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmin" %[[V:.*]] : (!cir.vector<8 x !cir.double>{{.*}}) -> !cir.double + // CIR: cir.vec.reduce(fmin, %[[V:.*]]) : (!cir.vector<8 x !cir.double>) -> !cir.double <fastmath_flags = [nnan]> + // CIR-NINF-LABEL: cir.func{{.*}} @_mm512_reduce_min_pd( + // CIR-NINF: cir.vec.reduce(fmin, {{.*}}) {{.*}} <fastmath_flags = [nnan, ninf]> // LLVM-LABEL: test_mm512_reduce_min_pd - // LLVM: call double @llvm.vector.reduce.fmin.v8f64(<8 x double> %{{.*}}) + // LLVM: call nnan double @llvm.vector.reduce.fmin.v8f64(<8 x double> %{{.*}}) + // LLVM-NINF-LABEL: define {{.*}} @test_mm512_reduce_min_pd( + // LLVM-NINF: call nnan ninf {{.*}}double @llvm.vector.reduce.fmin.v8f64( // OGCG-LABEL: test_mm512_reduce_min_pd // OGCG-NOT: nnan @@ -43,10 +54,10 @@ float test_mm512_reduce_max_ps(__m512 __W){ // CIR: cir.call @_mm512_reduce_max_ps(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<16 x !cir.float>{{.*}}) -> !cir.float // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_max_ps( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmax" %[[V:.*]] : (!cir.vector<16 x !cir.float>{{.*}}) -> !cir.float + // CIR: cir.vec.reduce(fmax, %[[V:.*]]) : (!cir.vector<16 x !cir.float>) -> !cir.float <fastmath_flags = [nnan]> // LLVM-LABEL: test_mm512_reduce_max_ps - // LLVM: call float @llvm.vector.reduce.fmax.v16f32(<16 x float> %{{.*}}) + // LLVM: call nnan float @llvm.vector.reduce.fmax.v16f32(<16 x float> %{{.*}}) // OGCG-LABEL: test_mm512_reduce_max_ps // OGCG: call nnan {{.*}}float @llvm.vector.reduce.fmax.v16f32(<16 x float> %{{.*}}) @@ -58,10 +69,10 @@ float test_mm512_reduce_min_ps(__m512 __W){ // CIR: cir.call @_mm512_reduce_min_ps(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<16 x !cir.float>{{.*}}) -> !cir.float // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_min_ps( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmin" %[[V:.*]] : (!cir.vector<16 x !cir.float>{{.*}}) -> !cir.float + // CIR: cir.vec.reduce(fmin, %[[V:.*]]) : (!cir.vector<16 x !cir.float>) -> !cir.float <fastmath_flags = [nnan]> // LLVM-LABEL: test_mm512_reduce_min_ps - // LLVM: call float @llvm.vector.reduce.fmin.v16f32(<16 x float> %{{.*}}) + // LLVM: call nnan float @llvm.vector.reduce.fmin.v16f32(<16 x float> %{{.*}}) // OGCG-LABEL: test_mm512_reduce_min_ps // OGCG: call nnan {{.*}}float @llvm.vector.reduce.fmin.v16f32(<16 x float> %{{.*}}) diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512fp16-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512fp16-builtins.c index 470b72075e2200f..13080f7f4272667 100644 --- a/clang/test/CIR/CodeGenBuiltins/X86/avx512fp16-builtins.c +++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512fp16-builtins.c @@ -70,10 +70,10 @@ _Float16 test_mm512_reduce_add_ph(__m512h __W) { // CIR: cir.call @_mm512_reduce_add_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<32 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_add_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[R:.*]], %[[V:.*]] : (!cir.f16{{.*}}, !cir.vector<32 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fadd, %[[V:.*]], %[[R:.*]]) : (!cir.vector<32 x !cir.f16>, !cir.f16) -> !cir.f16 <fastmath_flags = [reassoc]> // LLVM-LABEL: test_mm512_reduce_add_ph - // LLVM: call half @llvm.vector.reduce.fadd.v32f16(half -0.000000e+00, <32 x half> %{{.*}}) + // LLVM: call reassoc half @llvm.vector.reduce.fadd.v32f16(half -0.000000e+00, <32 x half> %{{.*}}) // OGCG-LABEL: test_mm512_reduce_add_ph // OGCG: call reassoc {{.*}}half @llvm.vector.reduce.fadd.v32f16(half -0.000000e+00, <32 x half> %{{.*}}) @@ -85,10 +85,10 @@ _Float16 test_mm512_reduce_mul_ph(__m512h __W) { // CIR: cir.call @_mm512_reduce_mul_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<32 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_mul_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmul" %[[R:.*]], %[[V:.*]] : (!cir.f16{{.*}}, !cir.vector<32 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fmul, %[[V:.*]], %[[R:.*]]) : (!cir.vector<32 x !cir.f16>, !cir.f16) -> !cir.f16 <fastmath_flags = [reassoc]> // LLVM-LABEL: test_mm512_reduce_mul_ph - // LLVM: call half @llvm.vector.reduce.fmul.v32f16(half 1.000000e+00, <32 x half> %{{.*}}) + // LLVM: call reassoc half @llvm.vector.reduce.fmul.v32f16(half 1.000000e+00, <32 x half> %{{.*}}) // OGCG-LABEL: test_mm512_reduce_mul_ph // OGCG: call reassoc {{.*}}half @llvm.vector.reduce.fmul.v32f16(half 1.000000e+00, <32 x half> %{{.*}}) @@ -100,10 +100,10 @@ _Float16 test_mm512_reduce_max_ph(__m512h __W) { // CIR: cir.call @_mm512_reduce_max_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<32 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_max_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmax" %[[V:.*]] (!cir.vector<32 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fmax, %[[V:.*]]) : (!cir.vector<32 x !cir.f16>) -> !cir.f16 <fastmath_flags = [nnan]> // LLVM-LABEL: test_mm512_reduce_max_ph - // LLVM: call half @llvm.vector.reduce.fmax.v32f16(<32 x half> %{{.*}}) + // LLVM: call nnan half @llvm.vector.reduce.fmax.v32f16(<32 x half> %{{.*}}) // OGCG-LABEL: test_mm512_reduce_max_ph // OGCG: call nnan {{.*}}half @llvm.vector.reduce.fmax.v32f16(<32 x half> %{{.*}}) @@ -115,10 +115,10 @@ _Float16 test_mm512_reduce_min_ph(__m512h __W) { // CIR: cir.call @_mm512_reduce_min_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<32 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm512_reduce_min_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmin" %[[V:.*]] (!cir.vector<32 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fmin, %[[V:.*]]) : (!cir.vector<32 x !cir.f16>) -> !cir.f16 <fastmath_flags = [nnan]> // LLVM-LABEL: test_mm512_reduce_min_ph - // LLVM: call half @llvm.vector.reduce.fmin.v32f16(<32 x half> %{{.*}}) + // LLVM: call nnan half @llvm.vector.reduce.fmin.v32f16(<32 x half> %{{.*}}) // OGCG-LABEL: test_mm512_reduce_min_ph // OGCG: call nnan {{.*}}half @llvm.vector.reduce.fmin.v32f16(<32 x half> %{{.*}}) diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512vlfp16-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512vlfp16-builtins.c index f6be98ca40dbf64..279e1c0c1f9eb16 100644 --- a/clang/test/CIR/CodeGenBuiltins/X86/avx512vlfp16-builtins.c +++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512vlfp16-builtins.c @@ -12,10 +12,10 @@ _Float16 test_mm256_reduce_add_ph(__m256h __W) { // CIR: cir.call @_mm256_reduce_add_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<16 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm256_reduce_add_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[R:.*]], %[[V:.*]] : (!cir.f16{{.*}}, !cir.vector<16 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fadd, %[[V:.*]], %[[R:.*]]) : (!cir.vector<16 x !cir.f16>, !cir.f16) -> !cir.f16 <fastmath_flags = [reassoc]> // LLVM-LABEL: test_mm256_reduce_add_ph - // LLVM: call half @llvm.vector.reduce.fadd.v16f16(half -0.000000e+00, <16 x half> %{{.*}}) + // LLVM: call reassoc half @llvm.vector.reduce.fadd.v16f16(half -0.000000e+00, <16 x half> %{{.*}}) // OGCG-LABEL: test_mm256_reduce_add_ph // OGCG: call reassoc {{.*}}@llvm.vector.reduce.fadd.v16f16(half -0.000000e+00, <16 x half> %{{.*}}) @@ -27,10 +27,10 @@ _Float16 test_mm256_reduce_mul_ph(__m256h __W) { // CIR: cir.call @_mm256_reduce_mul_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<16 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm256_reduce_mul_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmul" %[[R:.*]], %[[V:.*]] : (!cir.f16{{.*}}, !cir.vector<16 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fmul, %[[V:.*]], %[[R:.*]]) : (!cir.vector<16 x !cir.f16>, !cir.f16) -> !cir.f16 <fastmath_flags = [reassoc]> // LLVM-LABEL: test_mm256_reduce_mul_ph - // LLVM: call half @llvm.vector.reduce.fmul.v16f16(half 1.000000e+00, <16 x half> %{{.*}}) + // LLVM: call reassoc half @llvm.vector.reduce.fmul.v16f16(half 1.000000e+00, <16 x half> %{{.*}}) // OGCG-LABEL: test_mm256_reduce_mul_ph // OGCG: call reassoc {{.*}}@llvm.vector.reduce.fmul.v16f16(half 1.000000e+00, <16 x half> %{{.*}}) @@ -42,10 +42,10 @@ _Float16 test_mm256_reduce_max_ph(__m256h __W) { // CIR: cir.call @_mm256_reduce_max_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<16 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm256_reduce_max_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmax" %[[V:.*]] (!cir.vector<16 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fmax, %[[V:.*]]) : (!cir.vector<16 x !cir.f16>) -> !cir.f16 <fastmath_flags = [nnan]> // LLVM-LABEL: test_mm256_reduce_max_ph - // LLVM: call half @llvm.vector.reduce.fmax.v16f16(<16 x half> %{{.*}}) + // LLVM: call nnan half @llvm.vector.reduce.fmax.v16f16(<16 x half> %{{.*}}) // OGCG-LABEL: test_mm256_reduce_max_ph // OGCG: call nnan {{.*}}@llvm.vector.reduce.fmax.v16f16(<16 x half> %{{.*}}) @@ -57,10 +57,10 @@ _Float16 test_mm256_reduce_min_ph(__m256h __W) { // CIR: cir.call @_mm256_reduce_min_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<16 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm256_reduce_min_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmin" %[[V:.*]] : (!cir.vector<16 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fmin, %[[V:.*]]) : (!cir.vector<16 x !cir.f16>) -> !cir.f16 <fastmath_flags = [nnan]> // LLVM-LABEL: test_mm256_reduce_min_ph - // LLVM: call half @llvm.vector.reduce.fmin.v16f16(<16 x half> %{{.*}}) + // LLVM: call nnan half @llvm.vector.reduce.fmin.v16f16(<16 x half> %{{.*}}) // OGCG-LABEL: test_mm256_reduce_min_ph // OGCG: call nnan {{.*}}@llvm.vector.reduce.fmin.v16f16(<16 x half> %{{.*}}) @@ -72,10 +72,10 @@ _Float16 test_mm_reduce_add_ph(__m128h __W) { // CIR: cir.call @_mm_reduce_add_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<8 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm_reduce_add_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[R:.*]], %[[V:.*]] : (!cir.f16{{.*}}, !cir.vector<8 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fadd, %[[V:.*]], %[[R:.*]]) : (!cir.vector<8 x !cir.f16>, !cir.f16) -> !cir.f16 <fastmath_flags = [reassoc]> // LLVM-LABEL: test_mm_reduce_add_ph - // LLVM: call half @llvm.vector.reduce.fadd.v8f16(half -0.000000e+00, <8 x half> %{{.*}}) + // LLVM: call reassoc half @llvm.vector.reduce.fadd.v8f16(half -0.000000e+00, <8 x half> %{{.*}}) // OGCG-LABEL: test_mm_reduce_add_ph // OGCG: call reassoc {{.*}}@llvm.vector.reduce.fadd.v8f16(half -0.000000e+00, <8 x half> %{{.*}}) @@ -87,10 +87,10 @@ _Float16 test_mm_reduce_mul_ph(__m128h __W) { // CIR: cir.call @_mm_reduce_mul_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<8 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm_reduce_mul_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmul" %[[R:.*]], %[[V:.*]] : (!cir.f16{{.*}}, !cir.vector<8 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fmul, %[[V:.*]], %[[R:.*]]) : (!cir.vector<8 x !cir.f16>, !cir.f16) -> !cir.f16 <fastmath_flags = [reassoc]> // LLVM-LABEL: test_mm_reduce_mul_ph - // LLVM: call half @llvm.vector.reduce.fmul.v8f16(half 1.000000e+00, <8 x half> %{{.*}}) + // LLVM: call reassoc half @llvm.vector.reduce.fmul.v8f16(half 1.000000e+00, <8 x half> %{{.*}}) // OGCG-LABEL: test_mm_reduce_mul_ph // OGCG: call reassoc {{.*}}@llvm.vector.reduce.fmul.v8f16(half 1.000000e+00, <8 x half> %{{.*}}) @@ -102,10 +102,10 @@ _Float16 test_mm_reduce_max_ph(__m128h __W) { // CIR: cir.call @_mm_reduce_max_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<8 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm_reduce_max_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmax" %[[V:.*]] (!cir.vector<8 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fmax, %[[V:.*]]) : (!cir.vector<8 x !cir.f16>) -> !cir.f16 <fastmath_flags = [nnan]> // LLVM-LABEL: test_mm_reduce_max_ph - // LLVM: call half @llvm.vector.reduce.fmax.v8f16(<8 x half> %{{.*}}) + // LLVM: call nnan half @llvm.vector.reduce.fmax.v8f16(<8 x half> %{{.*}}) // OGCG-LABEL: test_mm_reduce_max_ph // OGCG: call nnan {{.*}}@llvm.vector.reduce.fmax.v8f16(<8 x half> %{{.*}}) @@ -117,13 +117,12 @@ _Float16 test_mm_reduce_min_ph(__m128h __W) { // CIR: cir.call @_mm_reduce_min_ph(%[[VEC:.*]]) {nobuiltin, nobuiltins = [{{.*}}]} : (!cir.vector<8 x !cir.f16>{{.*}}) -> !cir.f16 // CIR-LABEL: cir.func{{.*}} @_mm_reduce_min_ph( - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmin" %[[V:.*]] : (!cir.vector<8 x !cir.f16>{{.*}}) -> !cir.f16 + // CIR: cir.vec.reduce(fmin, %[[V:.*]]) : (!cir.vector<8 x !cir.f16>) -> !cir.f16 <fastmath_flags = [nnan]> // LLVM-LABEL: test_mm_reduce_min_ph - // LLVM: call half @llvm.vector.reduce.fmin.v8f16(<8 x half> %{{.*}}) + // LLVM: call nnan half @llvm.vector.reduce.fmin.v8f16(<8 x half> %{{.*}}) // OGCG-LABEL: test_mm_reduce_min_ph // OGCG: call nnan {{.*}}@llvm.vector.reduce.fmin.v8f16(<8 x half> %{{.*}}) return _mm_reduce_min_ph(__W); } - diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c index 2ce6bdad767279b..e9f092645ce161d 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c @@ -14,7 +14,7 @@ int test_sve_reduce_add(svint32_t x) { // CIR-LABEL: @test_sve_reduce_add - // CIR: cir.call_llvm_intrinsic "vector.reduce.add" + // CIR: cir.vec.reduce(add, // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_add // LLVM: call i32 @llvm.vector.reduce.add.nxv4i32(<vscale x 4 x i32> @@ -24,7 +24,7 @@ int test_sve_reduce_add(svint32_t x) { int test_sve_reduce_mul(svint32_t x) { // CIR-LABEL: @test_sve_reduce_mul - // CIR: cir.call_llvm_intrinsic "vector.reduce.mul" + // CIR: cir.vec.reduce(mul, // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_mul // LLVM: call i32 @llvm.vector.reduce.mul.nxv4i32(<vscale x 4 x i32> @@ -34,7 +34,7 @@ int test_sve_reduce_mul(svint32_t x) { int test_sve_reduce_max(svint32_t x) { // CIR-LABEL: @test_sve_reduce_max - // CIR: cir.call_llvm_intrinsic "vector.reduce.smax" + // CIR: cir.vec.reduce(smax, // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_max // LLVM: call i32 @llvm.vector.reduce.smax.nxv4i32(<vscale x 4 x i32> @@ -44,7 +44,7 @@ int test_sve_reduce_max(svint32_t x) { unsigned test_sve_reduce_max_unsigned(svuint32_t x) { // CIR-LABEL: @test_sve_reduce_max_unsigned - // CIR: cir.call_llvm_intrinsic "vector.reduce.umax" + // CIR: cir.vec.reduce(umax, // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_max_unsigned // LLVM: call i32 @llvm.vector.reduce.umax.nxv4i32(<vscale x 4 x i32> @@ -54,7 +54,7 @@ unsigned test_sve_reduce_max_unsigned(svuint32_t x) { float test_sve_reduce_max_float(svfloat32_t x) { // CIR-LABEL: @test_sve_reduce_max_float - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmax" + // CIR: cir.vec.reduce(fmax, // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_max_float // LLVM: call float @llvm.vector.reduce.fmax.nxv4f32(<vscale x 4 x float> @@ -64,7 +64,7 @@ float test_sve_reduce_max_float(svfloat32_t x) { int test_sve_reduce_min(svint32_t x) { // CIR-LABEL: @test_sve_reduce_min - // CIR: cir.call_llvm_intrinsic "vector.reduce.smin" + // CIR: cir.vec.reduce(smin, // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_min // LLVM: call i32 @llvm.vector.reduce.smin.nxv4i32(<vscale x 4 x i32> @@ -74,7 +74,7 @@ int test_sve_reduce_min(svint32_t x) { unsigned test_sve_reduce_min_unsigned(svuint32_t x) { // CIR-LABEL: @test_sve_reduce_min_unsigned - // CIR: cir.call_llvm_intrinsic "vector.reduce.umin" + // CIR: cir.vec.reduce(umin, // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_min_unsigned // LLVM: call i32 @llvm.vector.reduce.umin.nxv4i32(<vscale x 4 x i32> @@ -84,7 +84,7 @@ unsigned test_sve_reduce_min_unsigned(svuint32_t x) { float test_sve_reduce_min_float(svfloat32_t x) { // CIR-LABEL: @test_sve_reduce_min_float - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmin" + // CIR: cir.vec.reduce(fmin, // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_min_float // LLVM: call float @llvm.vector.reduce.fmin.nxv4f32(<vscale x 4 x float> @@ -94,7 +94,7 @@ float test_sve_reduce_min_float(svfloat32_t x) { float test_sve_reduce_assoc_fadd(svfloat32_t x, float start) { // CIR-LABEL: @test_sve_reduce_assoc_fadd - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<[4] x !cir.float>) -> !cir.float fastmath<reassoc> + // CIR: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<[4] x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_assoc_fadd // LLVM: call reassoc float @llvm.vector.reduce.fadd.nxv4f32(float %{{.*}}, <vscale x 4 x float> @@ -105,7 +105,7 @@ float test_sve_reduce_assoc_fadd(svfloat32_t x, float start) { float test_sve_reduce_assoc_fadd_default_start(svfloat32_t x) { // CIR-LABEL: @test_sve_reduce_assoc_fadd_default_start // CIR: %[[START:.*]] = cir.const #cir.fp<-0.000000e+00> : !cir.float - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[START]], {{.*}} : (!cir.float, !cir.vector<[4] x !cir.float>) -> !cir.float fastmath<reassoc> + // CIR: cir.vec.reduce(fadd, {{.*}}, %[[START]]) : (!cir.vector<[4] x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_assoc_fadd_default_start // LLVM: call reassoc float @llvm.vector.reduce.fadd.nxv4f32(float -0.000000e+00, <vscale x 4 x float> @@ -115,8 +115,7 @@ float test_sve_reduce_assoc_fadd_default_start(svfloat32_t x) { float test_sve_reduce_in_order_fadd(svfloat32_t x, float start) { // CIR-LABEL: @test_sve_reduce_in_order_fadd - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<[4] x !cir.float>) -> !cir.float - // CIR-NOT: fastmath_flags + // CIR: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<[4] x !cir.float>, !cir.float) -> !cir.float{{( loc.*)?$}} // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_in_order_fadd // LLVM: call float @llvm.vector.reduce.fadd.nxv4f32(float %{{.*}}, <vscale x 4 x float> @@ -127,7 +126,7 @@ float test_sve_reduce_in_order_fadd(svfloat32_t x, float start) { float test_sve_reduce_in_order_fadd_cast_start(svfloat32_t x, double start) { // CIR-LABEL: @test_sve_reduce_in_order_fadd_cast_start // CIR: cir.cast floating {{.*}} : !cir.double -> !cir.float - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<[4] x !cir.float>) -> !cir.float + // CIR: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<[4] x !cir.float>, !cir.float) -> !cir.float // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_in_order_fadd_cast_start // LLVM: fptrunc double %{{.*}} to float @@ -138,7 +137,7 @@ float test_sve_reduce_in_order_fadd_cast_start(svfloat32_t x, double start) { double test_sve_reduce_in_order_fadd_double(svfloat64_t x, double start) { // CIR-LABEL: @test_sve_reduce_in_order_fadd_double - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.double, !cir.vector<[2] x !cir.double>) -> !cir.double + // CIR: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<[2] x !cir.double>, !cir.double) -> !cir.double // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_in_order_fadd_double // LLVM: call double @llvm.vector.reduce.fadd.nxv2f64(double %{{.*}}, <vscale x 2 x double> diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c index 57408af5d80d461..85bda3f284026d4 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c @@ -9,10 +9,11 @@ typedef int v4si __attribute__((vector_size(16))); typedef unsigned int v4su __attribute__((vector_size(16))); typedef float v4sf __attribute__((vector_size(16))); typedef double v2df __attribute__((vector_size(16))); +typedef _Bool v4b __attribute__((ext_vector_type(4))); int test_reduce_add(v4si x) { // CIR-LABEL: @test_reduce_add - // CIR: cir.call_llvm_intrinsic "vector.reduce.add" + // CIR: cir.vec.reduce(add, // CIR: cir.return // LLVM-LABEL: @test_reduce_add // LLVM: call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> @@ -22,7 +23,7 @@ int test_reduce_add(v4si x) { unsigned test_reduce_add_unsigned(v4su x) { // CIR-LABEL: @test_reduce_add_unsigned - // CIR: cir.call_llvm_intrinsic "vector.reduce.add" + // CIR: cir.vec.reduce(add, // CIR: cir.return // LLVM-LABEL: @test_reduce_add_unsigned // LLVM: call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> @@ -30,9 +31,20 @@ unsigned test_reduce_add_unsigned(v4su x) { return __builtin_reduce_add(x); } +_Bool test_reduce_add_bool(void) { + // CIR-LABEL: @test_reduce_add_bool + // CIR: cir.vec.reduce(add, {{.*}}) : (!cir.vector<4 x !cir.bool>) -> !cir.bool + // CIR: cir.return + // LLVM-LABEL: @test_reduce_add_bool + // LLVM: call i1 @llvm.vector.reduce.add.v4i1(<4 x i1> + // LLVM: ret i1 + v4b x = {1, 0, 1, 0}; + return __builtin_reduce_add(x); +} + int test_reduce_mul(v4si x) { // CIR-LABEL: @test_reduce_mul - // CIR: cir.call_llvm_intrinsic "vector.reduce.mul" + // CIR: cir.vec.reduce(mul, // CIR: cir.return // LLVM-LABEL: @test_reduce_mul // LLVM: call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> @@ -42,7 +54,7 @@ int test_reduce_mul(v4si x) { unsigned test_reduce_mul_unsigned(v4su x) { // CIR-LABEL: @test_reduce_mul_unsigned - // CIR: cir.call_llvm_intrinsic "vector.reduce.mul" + // CIR: cir.vec.reduce(mul, // CIR: cir.return // LLVM-LABEL: @test_reduce_mul_unsigned // LLVM: call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> @@ -52,7 +64,7 @@ unsigned test_reduce_mul_unsigned(v4su x) { int test_reduce_max(v4si x) { // CIR-LABEL: @test_reduce_max - // CIR: cir.call_llvm_intrinsic "vector.reduce.smax" + // CIR: cir.vec.reduce(smax, // CIR: cir.return // LLVM-LABEL: @test_reduce_max // LLVM: call i32 @llvm.vector.reduce.smax.v4i32(<4 x i32> @@ -62,7 +74,7 @@ int test_reduce_max(v4si x) { unsigned test_reduce_max_unsigned(v4su x) { // CIR-LABEL: @test_reduce_max_unsigned - // CIR: cir.call_llvm_intrinsic "vector.reduce.umax" + // CIR: cir.vec.reduce(umax, // CIR: cir.return // LLVM-LABEL: @test_reduce_max_unsigned // LLVM: call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> @@ -70,9 +82,20 @@ unsigned test_reduce_max_unsigned(v4su x) { return __builtin_reduce_max(x); } +_Bool test_reduce_max_bool(void) { + // CIR-LABEL: @test_reduce_max_bool + // CIR: cir.vec.reduce(umax, {{.*}}) : (!cir.vector<4 x !cir.bool>) -> !cir.bool + // CIR: cir.return + // LLVM-LABEL: @test_reduce_max_bool + // LLVM: call i1 @llvm.vector.reduce.umax.v4i1(<4 x i1> + // LLVM: ret i1 + v4b x = {1, 0, 1, 0}; + return __builtin_reduce_max(x); +} + float test_reduce_max_float(v4sf x) { // CIR-LABEL: @test_reduce_max_float - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmax" + // CIR: cir.vec.reduce(fmax, // CIR: cir.return // LLVM-LABEL: @test_reduce_max_float // LLVM: call float @llvm.vector.reduce.fmax.v4f32(<4 x float> @@ -82,7 +105,7 @@ float test_reduce_max_float(v4sf x) { int test_reduce_min(v4si x) { // CIR-LABEL: @test_reduce_min - // CIR: cir.call_llvm_intrinsic "vector.reduce.smin" + // CIR: cir.vec.reduce(smin, // CIR: cir.return // LLVM-LABEL: @test_reduce_min // LLVM: call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> @@ -92,7 +115,7 @@ int test_reduce_min(v4si x) { unsigned test_reduce_min_unsigned(v4su x) { // CIR-LABEL: @test_reduce_min_unsigned - // CIR: cir.call_llvm_intrinsic "vector.reduce.umin" + // CIR: cir.vec.reduce(umin, // CIR: cir.return // LLVM-LABEL: @test_reduce_min_unsigned // LLVM: call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> @@ -102,7 +125,7 @@ unsigned test_reduce_min_unsigned(v4su x) { float test_reduce_min_float(v4sf x) { // CIR-LABEL: @test_reduce_min_float - // CIR: cir.call_llvm_intrinsic "vector.reduce.fmin" + // CIR: cir.vec.reduce(fmin, // CIR: cir.return // LLVM-LABEL: @test_reduce_min_float // LLVM: call float @llvm.vector.reduce.fmin.v4f32(<4 x float> @@ -112,7 +135,7 @@ float test_reduce_min_float(v4sf x) { float test_reduce_assoc_fadd(v4sf x, float start) { // CIR-LABEL: @test_reduce_assoc_fadd - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<4 x !cir.float>) -> !cir.float fastmath<reassoc> + // CIR: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> // CIR: cir.return // LLVM-LABEL: @test_reduce_assoc_fadd // LLVM: call reassoc float @llvm.vector.reduce.fadd.v4f32(float %{{.*}}, <4 x float> @@ -123,7 +146,7 @@ float test_reduce_assoc_fadd(v4sf x, float start) { float test_reduce_assoc_fadd_default_start(v4sf x) { // CIR-LABEL: @test_reduce_assoc_fadd_default_start // CIR: %[[START:.*]] = cir.const #cir.fp<-0.000000e+00> : !cir.float - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[START]], {{.*}} : (!cir.float, !cir.vector<4 x !cir.float>) -> !cir.float fastmath<reassoc> + // CIR: cir.vec.reduce(fadd, {{.*}}, %[[START]]) : (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> // CIR: cir.return // LLVM-LABEL: @test_reduce_assoc_fadd_default_start // LLVM: call reassoc float @llvm.vector.reduce.fadd.v4f32(float -0.000000e+00, <4 x float> @@ -134,7 +157,7 @@ float test_reduce_assoc_fadd_default_start(v4sf x) { float test_reduce_assoc_fadd_cast_start(v4sf x, double start) { // CIR-LABEL: @test_reduce_assoc_fadd_cast_start // CIR: %[[START:.*]] = cir.cast floating {{.*}} : !cir.double -> !cir.float - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[START]], {{.*}} : (!cir.float, !cir.vector<4 x !cir.float>) -> !cir.float fastmath<reassoc> + // CIR: cir.vec.reduce(fadd, {{.*}}, %[[START]]) : (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> // CIR: cir.return // LLVM-LABEL: @test_reduce_assoc_fadd_cast_start // LLVM: %[[START:.*]] = fptrunc double %{{.*}} to float @@ -145,8 +168,7 @@ float test_reduce_assoc_fadd_cast_start(v4sf x, double start) { float test_reduce_in_order_fadd(v4sf x, float start) { // CIR-LABEL: @test_reduce_in_order_fadd - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<4 x !cir.float>) -> !cir.float - // CIR-NOT: fastmath_flags + // CIR: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float{{( loc.*)?$}} // CIR: cir.return // LLVM-LABEL: @test_reduce_in_order_fadd // LLVM: call float @llvm.vector.reduce.fadd.v4f32(float %{{.*}}, <4 x float> @@ -157,7 +179,7 @@ float test_reduce_in_order_fadd(v4sf x, float start) { float test_reduce_in_order_fadd_cast_start(v4sf x, double start) { // CIR-LABEL: @test_reduce_in_order_fadd_cast_start // CIR: cir.cast floating {{.*}} : !cir.double -> !cir.float - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<4 x !cir.float>) -> !cir.float + // CIR: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float // CIR: cir.return // LLVM-LABEL: @test_reduce_in_order_fadd_cast_start // LLVM: fptrunc double %{{.*}} to float @@ -168,7 +190,7 @@ float test_reduce_in_order_fadd_cast_start(v4sf x, double start) { double test_reduce_in_order_fadd_double(v2df x, double start) { // CIR-LABEL: @test_reduce_in_order_fadd_double - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.double, !cir.vector<2 x !cir.double>) -> !cir.double + // CIR: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<2 x !cir.double>, !cir.double) -> !cir.double // CIR: cir.return // LLVM-LABEL: @test_reduce_in_order_fadd_double // LLVM: call double @llvm.vector.reduce.fadd.v2f64(double %{{.*}}, <2 x double> @@ -179,7 +201,7 @@ double test_reduce_in_order_fadd_double(v2df x, double start) { double test_reduce_in_order_fadd_ext_start(v2df x, float start) { // CIR-LABEL: @test_reduce_in_order_fadd_ext_start // CIR: cir.cast floating {{.*}} : !cir.float -> !cir.double - // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.double, !cir.vector<2 x !cir.double>) -> !cir.double + // CIR: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<2 x !cir.double>, !cir.double) -> !cir.double // CIR: cir.return // LLVM-LABEL: @test_reduce_in_order_fadd_ext_start // LLVM: fpext float %{{.*}} to double diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-bitwise.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-bitwise.c index 0036c62201ee0b1..a5b4bbb7bce406a 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-bitwise.c +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-bitwise.c @@ -7,10 +7,11 @@ typedef int v4si __attribute__((vector_size(16))); typedef unsigned int v4su __attribute__((vector_size(16))); +typedef _Bool v4b __attribute__((ext_vector_type(4))); int test_reduce_or(v4si x) { // CIR-LABEL: @test_reduce_or - // CIR: cir.call_llvm_intrinsic "vector.reduce.or" + // CIR: cir.vec.reduce(or, // CIR: cir.return // LLVM-LABEL: @test_reduce_or // LLVM: call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> @@ -20,7 +21,7 @@ int test_reduce_or(v4si x) { int test_reduce_and(v4si x) { // CIR-LABEL: @test_reduce_and - // CIR: cir.call_llvm_intrinsic "vector.reduce.and" + // CIR: cir.vec.reduce(and, // CIR: cir.return // LLVM-LABEL: @test_reduce_and // LLVM: call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> @@ -28,9 +29,20 @@ int test_reduce_and(v4si x) { return __builtin_reduce_and(x); } +_Bool test_reduce_and_bool(void) { + // CIR-LABEL: @test_reduce_and_bool + // CIR: cir.vec.reduce(and, {{.*}}) : (!cir.vector<4 x !cir.bool>) -> !cir.bool + // CIR: cir.return + // LLVM-LABEL: @test_reduce_and_bool + // LLVM: call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> + // LLVM: ret i1 + v4b x = {1, 0, 1, 0}; + return __builtin_reduce_and(x); +} + int test_reduce_xor(v4si x) { // CIR-LABEL: @test_reduce_xor - // CIR: cir.call_llvm_intrinsic "vector.reduce.xor" + // CIR: cir.vec.reduce(xor, // CIR: cir.return // LLVM-LABEL: @test_reduce_xor // LLVM: call i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> @@ -40,7 +52,7 @@ int test_reduce_xor(v4si x) { unsigned test_reduce_or_unsigned(v4su x) { // CIR-LABEL: @test_reduce_or_unsigned - // CIR: cir.call_llvm_intrinsic "vector.reduce.or" + // CIR: cir.vec.reduce(or, // CIR: cir.return // LLVM-LABEL: @test_reduce_or_unsigned // LLVM: call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-fast-math.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-fast-math.c new file mode 100644 index 000000000000000..23bed21eb8390ae --- /dev/null +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-fast-math.c @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir \ +// RUN: -menable-no-nans %s -o - | FileCheck %s --check-prefix=CIR-NNAN +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm \ +// RUN: -menable-no-nans %s -o - | FileCheck %s --check-prefix=LLVM-NNAN +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm \ +// RUN: -menable-no-nans %s -o - | FileCheck %s --check-prefix=LLVM-NNAN +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir \ +// RUN: -ffast-math -ffp-contract=fast %s -o - | FileCheck %s --check-prefix=CIR-FAST +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm \ +// RUN: -ffast-math -ffp-contract=fast %s -o - | FileCheck %s --check-prefix=LLVM-FAST +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm \ +// RUN: -ffast-math -ffp-contract=fast %s -o - | FileCheck %s --check-prefix=LLVM-FAST +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir \ +// RUN: -mreassociate %s -o - | FileCheck %s --check-prefix=CIR-PRAGMA +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm \ +// RUN: -mreassociate %s -o - | FileCheck %s --check-prefix=LLVM-PRAGMA +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm \ +// RUN: -mreassociate %s -o - | FileCheck %s --check-prefix=LLVM-PRAGMA + +typedef float v4sf __attribute__((vector_size(16))); +typedef int v4si __attribute__((vector_size(16))); + +float test_assoc(v4sf x, float start) { + // CIR-NNAN-LABEL: @test_assoc + // CIR-NNAN: cir.vec.reduce(fadd, {{.*}}) {{.*}} <fastmath_flags = [nnan, reassoc]> + // CIR-FAST-LABEL: @test_assoc + // CIR-FAST: cir.vec.reduce(fadd, {{.*}}) {{.*}} <fastmath_flags = [fast]> + // LLVM-NNAN-LABEL: @test_assoc + // LLVM-NNAN: call reassoc nnan float @llvm.vector.reduce.fadd.v4f32( + // LLVM-FAST-LABEL: @test_assoc + // LLVM-FAST: call fast float @llvm.vector.reduce.fadd.v4f32( + return __builtin_reduce_assoc_fadd(x, start); +} + +float test_in_order(v4sf x, float start) { + // CIR-NNAN-LABEL: @test_in_order + // CIR-NNAN: cir.vec.reduce(fadd, {{.*}}) {{.*}} <fastmath_flags = [nnan]> + // CIR-FAST-LABEL: @test_in_order + // CIR-FAST: cir.vec.reduce(fadd, {{.*}}) {{.*}} <fastmath_flags = [fast]> + // LLVM-NNAN-LABEL: @test_in_order + // LLVM-NNAN: call nnan float @llvm.vector.reduce.fadd.v4f32( + // LLVM-FAST-LABEL: @test_in_order + // LLVM-FAST: call fast float @llvm.vector.reduce.fadd.v4f32( + return __builtin_reduce_in_order_fadd(x, start); +} + +float test_max(v4sf x) { + // CIR-NNAN-LABEL: @test_max + // CIR-NNAN: cir.vec.reduce(fmax, {{.*}}) {{.*}} <fastmath_flags = [nnan]> + // CIR-FAST-LABEL: @test_max + // CIR-FAST: cir.vec.reduce(fmax, {{.*}}) {{.*}} <fastmath_flags = [fast]> + // LLVM-NNAN-LABEL: @test_max + // LLVM-NNAN: call nnan float @llvm.vector.reduce.fmax.v4f32( + // LLVM-FAST-LABEL: @test_max + // LLVM-FAST: call fast float @llvm.vector.reduce.fmax.v4f32( + return __builtin_reduce_max(x); +} + +float test_min(v4sf x) { + // CIR-NNAN-LABEL: @test_min + // CIR-NNAN: cir.vec.reduce(fmin, {{.*}}) {{.*}} <fastmath_flags = [nnan]> + // CIR-FAST-LABEL: @test_min + // CIR-FAST: cir.vec.reduce(fmin, {{.*}}) {{.*}} <fastmath_flags = [fast]> + // LLVM-NNAN-LABEL: @test_min + // LLVM-NNAN: call nnan float @llvm.vector.reduce.fmin.v4f32( + // LLVM-FAST-LABEL: @test_min + // LLVM-FAST: call fast float @llvm.vector.reduce.fmin.v4f32( + return __builtin_reduce_min(x); +} + +int test_int_max(v4si x) { + // CIR-NNAN-LABEL: @test_int_max + // CIR-NNAN: cir.vec.reduce(smax, {{.*}}) : (!cir.vector<4 x !s32i>) -> !s32i{{( loc.*)?$}} + // CIR-FAST-LABEL: @test_int_max + // CIR-FAST: cir.vec.reduce(smax, {{.*}}) : (!cir.vector<4 x !s32i>) -> !s32i{{( loc.*)?$}} + // LLVM-NNAN-LABEL: @test_int_max + // LLVM-NNAN: call i32 @llvm.vector.reduce.smax.v4i32( + // LLVM-FAST-LABEL: @test_int_max + // LLVM-FAST: call i32 @llvm.vector.reduce.smax.v4i32( + return __builtin_reduce_max(x); +} + +float test_pragma_reassociate(v4sf x, float start) { +#pragma clang fp reassociate(on) + // CIR-PRAGMA-LABEL: @test_pragma_reassociate + // CIR-PRAGMA: cir.vec.reduce(fadd, {{.*}}) {{.*}} <fastmath_flags = [reassoc]> + // LLVM-PRAGMA-LABEL: @test_pragma_reassociate + // LLVM-PRAGMA: call reassoc float @llvm.vector.reduce.fadd.v4f32( + return __builtin_reduce_in_order_fadd(x, start); +} + +float test_pragma_no_reassociate(v4sf x, float start) { +#pragma clang fp reassociate(off) + // CIR-PRAGMA-LABEL: @test_pragma_no_reassociate + // CIR-PRAGMA: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float{{( loc.*)?$}} + // LLVM-PRAGMA-LABEL: @test_pragma_no_reassociate + // LLVM-PRAGMA: call float @llvm.vector.reduce.fadd.v4f32( + return __builtin_reduce_in_order_fadd(x, start); +} diff --git a/clang/test/CIR/IR/invalid-vector-reduce.cir b/clang/test/CIR/IR/invalid-vector-reduce.cir new file mode 100644 index 000000000000000..ea13f67092e8dec --- /dev/null +++ b/clang/test/CIR/IR/invalid-vector-reduce.cir @@ -0,0 +1,78 @@ +// RUN: cir-opt %s -verify-diagnostics -split-input-file + +!f32 = !cir.float +!v4f32 = !cir.vector<4 x !f32> + +module { + cir.func @missing_accumulator(%vec: !v4f32) { + // expected-error @below {{'cir.vec.reduce' op requires an accumulator for fadd reduction}} + %0 = cir.vec.reduce(fadd, %vec) : (!v4f32) -> !f32 + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> +!v4s32 = !cir.vector<4 x !s32i> + +module { + cir.func @unexpected_accumulator(%vec: !v4s32, %start: !s32i) { + // expected-error @below {{'cir.vec.reduce' op does not accept an accumulator for add reduction}} + %0 = cir.vec.reduce(add, %vec, %start) : (!v4s32, !s32i) -> !s32i + cir.return + } +} + +// ----- + +!f32 = !cir.float +!v4f32 = !cir.vector<4 x !f32> + +module { + cir.func @wrong_vector_type(%vec: !v4f32) { + // expected-error @below {{'cir.vec.reduce' op requires an integer or boolean vector for add reduction}} + %0 = cir.vec.reduce(add, %vec) : (!v4f32) -> !f32 + cir.return + } +} + +// ----- + +!u32i = !cir.int<u, 32> +!v4u32 = !cir.vector<4 x !u32i> + +module { + cir.func @wrong_signedness(%vec: !v4u32) { + // expected-error @below {{'cir.vec.reduce' op requires a signed integer vector for smax reduction}} + %0 = cir.vec.reduce(smax, %vec) : (!v4u32) -> !u32i + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> +!v4s32 = !cir.vector<4 x !s32i> + +module { + cir.func @integer_fastmath(%vec: !v4s32) { + // expected-error @below {{'cir.vec.reduce' op fast-math flags are only valid for floating-point reductions}} + %0 = cir.vec.reduce(add, %vec) : (!v4s32) -> !s32i <fastmath_flags = [reassoc]> + cir.return + } +} + +// ----- + +!f32 = !cir.float +!f64 = !cir.double +!v4f32 = !cir.vector<4 x !f32> + +module { + cir.func @wrong_accumulator_type(%vec: !v4f32, %start: !f64) { + // expected-error @below {{'cir.vec.reduce' op accumulator type '!cir.double' doesn't match vector element type '!cir.float'}} + %0 = cir.vec.reduce(fadd, %vec, %start) : (!v4f32, !f64) -> !f32 + cir.return + } +} diff --git a/clang/test/CIR/IR/vector.cir b/clang/test/CIR/IR/vector.cir index d744d6f07676347..7b96f562485e205 100644 --- a/clang/test/CIR/IR/vector.cir +++ b/clang/test/CIR/IR/vector.cir @@ -1,6 +1,7 @@ // RUN: cir-opt %s --verify-roundtrip | FileCheck %s !s32i = !cir.int<s, 32> +!u32i = !cir.int<u, 32> module { @@ -222,4 +223,46 @@ cir.func @vector_splat_test() { // CHECK-NEXT: cir.store %[[SHL]], %[[SHL_RES:.*]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> // CHECK-NEXT: cir.return +cir.func @vector_reduce_test(%svec: !cir.vector<4 x !s32i>, + %uvec: !cir.vector<4 x !u32i>, + %fvec: !cir.vector<4 x !cir.float>, + %bvec: !cir.vector<4 x !cir.bool>, + %start: !cir.float) { + %0 = cir.vec.reduce(add, %svec) : (!cir.vector<4 x !s32i>) -> !s32i + %1 = cir.vec.reduce(mul, %svec) : (!cir.vector<4 x !s32i>) -> !s32i + %2 = cir.vec.reduce(and, %svec) : (!cir.vector<4 x !s32i>) -> !s32i + %3 = cir.vec.reduce(or, %svec) : (!cir.vector<4 x !s32i>) -> !s32i + %4 = cir.vec.reduce(xor, %svec) : (!cir.vector<4 x !s32i>) -> !s32i + %5 = cir.vec.reduce(smax, %svec) : (!cir.vector<4 x !s32i>) -> !s32i + %6 = cir.vec.reduce(smin, %svec) : (!cir.vector<4 x !s32i>) -> !s32i + %7 = cir.vec.reduce(umax, %uvec) : (!cir.vector<4 x !u32i>) -> !u32i + %8 = cir.vec.reduce(umin, %uvec) : (!cir.vector<4 x !u32i>) -> !u32i + %9 = cir.vec.reduce(fadd, %fvec, %start) : (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> + %10 = cir.vec.reduce(fmul, %fvec, %start) : (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> + %11 = cir.vec.reduce(fmax, %fvec) : (!cir.vector<4 x !cir.float>) -> !cir.float <fastmath_flags = [nnan]> + %12 = cir.vec.reduce(fmin, %fvec) : (!cir.vector<4 x !cir.float>) -> !cir.float <fastmath_flags = [nnan]> + %13 = cir.vec.reduce(add, %bvec) : (!cir.vector<4 x !cir.bool>) -> !cir.bool + %14 = cir.vec.reduce(umax, %bvec) : (!cir.vector<4 x !cir.bool>) -> !cir.bool + %15 = cir.vec.reduce(and, %bvec) : (!cir.vector<4 x !cir.bool>) -> !cir.bool + cir.return +} + +// CHECK-LABEL: cir.func @vector_reduce_test +// CHECK: cir.vec.reduce(add, +// CHECK: cir.vec.reduce(mul, +// CHECK: cir.vec.reduce(and, +// CHECK: cir.vec.reduce(or, +// CHECK: cir.vec.reduce(xor, +// CHECK: cir.vec.reduce(smax, +// CHECK: cir.vec.reduce(smin, +// CHECK: cir.vec.reduce(umax, +// CHECK: cir.vec.reduce(umin, +// CHECK: cir.vec.reduce(fadd, {{.*}}) : (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> +// CHECK: cir.vec.reduce(fmul, {{.*}}) : (!cir.vector<4 x !cir.float>, !cir.float) -> !cir.float <fastmath_flags = [reassoc]> +// CHECK: cir.vec.reduce(fmax, {{.*}}) : (!cir.vector<4 x !cir.float>) -> !cir.float <fastmath_flags = [nnan]> +// CHECK: cir.vec.reduce(fmin, {{.*}}) : (!cir.vector<4 x !cir.float>) -> !cir.float <fastmath_flags = [nnan]> +// CHECK: cir.vec.reduce(add, {{.*}}) : (!cir.vector<4 x !cir.bool>) -> !cir.bool +// CHECK: cir.vec.reduce(umax, {{.*}}) : (!cir.vector<4 x !cir.bool>) -> !cir.bool +// CHECK: cir.vec.reduce(and, {{.*}}) : (!cir.vector<4 x !cir.bool>) -> !cir.bool + } diff --git a/clang/test/CIR/Lowering/vector-reduce.cir b/clang/test/CIR/Lowering/vector-reduce.cir new file mode 100644 index 000000000000000..e8a67176b1206f6 --- /dev/null +++ b/clang/test/CIR/Lowering/vector-reduce.cir @@ -0,0 +1,50 @@ +// RUN: cir-opt %s -cir-to-llvm -o - | FileCheck %s + +!s32i = !cir.int<s, 32> +!u32i = !cir.int<u, 32> +!f32 = !cir.float +!v4s32 = !cir.vector<4 x !s32i> +!v4u32 = !cir.vector<4 x !u32i> +!v4f32 = !cir.vector<4 x !f32> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // CHECK-LABEL: llvm.func @vector_reduce + // CHECK: "llvm.intr.vector.reduce.add" + // CHECK: "llvm.intr.vector.reduce.mul" + // CHECK: "llvm.intr.vector.reduce.and" + // CHECK: "llvm.intr.vector.reduce.or" + // CHECK: "llvm.intr.vector.reduce.xor" + // CHECK: "llvm.intr.vector.reduce.smax" + // CHECK: "llvm.intr.vector.reduce.smin" + // CHECK: "llvm.intr.vector.reduce.umax" + // CHECK: "llvm.intr.vector.reduce.umin" + // CHECK: llvm.intr.vector.reduce.fadd(%{{.*}}, %{{.*}}) fastmath<reassoc> : (f32, vector<4xf32>) -> f32 + // CHECK: llvm.intr.vector.reduce.fmul(%{{.*}}, %{{.*}}) fastmath<reassoc> : (f32, vector<4xf32>) -> f32 + // CHECK: llvm.intr.vector.reduce.fmax(%{{.*}}) fastmath<nnan> : (vector<4xf32>) -> f32 + // CHECK: llvm.intr.vector.reduce.fmin(%{{.*}}) fastmath<nnan> : (vector<4xf32>) -> f32 + // CHECK: "llvm.intr.vector.reduce.add"(%{{.*}}) : (vector<4xi1>) -> i1 + // CHECK: "llvm.intr.vector.reduce.umax"(%{{.*}}) : (vector<4xi1>) -> i1 + // CHECK: "llvm.intr.vector.reduce.and"(%{{.*}}) : (vector<4xi1>) -> i1 + // CHECK: llvm.return + cir.func @vector_reduce(%svec: !v4s32, %uvec: !v4u32, + %fvec: !v4f32, + %bvec: !cir.vector<4 x !cir.bool>, %start: !f32) { + %0 = cir.vec.reduce(add, %svec) : (!v4s32) -> !s32i + %1 = cir.vec.reduce(mul, %svec) : (!v4s32) -> !s32i + %2 = cir.vec.reduce(and, %svec) : (!v4s32) -> !s32i + %3 = cir.vec.reduce(or, %svec) : (!v4s32) -> !s32i + %4 = cir.vec.reduce(xor, %svec) : (!v4s32) -> !s32i + %5 = cir.vec.reduce(smax, %svec) : (!v4s32) -> !s32i + %6 = cir.vec.reduce(smin, %svec) : (!v4s32) -> !s32i + %7 = cir.vec.reduce(umax, %uvec) : (!v4u32) -> !u32i + %8 = cir.vec.reduce(umin, %uvec) : (!v4u32) -> !u32i + %9 = cir.vec.reduce(fadd, %fvec, %start) : (!v4f32, !f32) -> !f32 <fastmath_flags = [reassoc]> + %10 = cir.vec.reduce(fmul, %fvec, %start) : (!v4f32, !f32) -> !f32 <fastmath_flags = [reassoc]> + %11 = cir.vec.reduce(fmax, %fvec) : (!v4f32) -> !f32 <fastmath_flags = [nnan]> + %12 = cir.vec.reduce(fmin, %fvec) : (!v4f32) -> !f32 <fastmath_flags = [nnan]> + %13 = cir.vec.reduce(add, %bvec) : (!cir.vector<4 x !cir.bool>) -> !cir.bool + %14 = cir.vec.reduce(umax, %bvec) : (!cir.vector<4 x !cir.bool>) -> !cir.bool + %15 = cir.vec.reduce(and, %bvec) : (!cir.vector<4 x !cir.bool>) -> !cir.bool + cir.return + } +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
