https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/185278
>From 808f406ee2c8137e1bfb30cde2b44f3ba33a4e18 Mon Sep 17 00:00:00 2001 From: xlauko <[email protected]> Date: Sat, 7 Mar 2026 14:19:44 +0100 Subject: [PATCH] [CIR] Remove cir.unary(plus, ...) and emit nothing for unary plus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Traditional codegen never emits any operation for unary plus — it just visits the subexpression as a pure identity at the codegen level. Align CIRGen with this behavior by removing Plus from UnaryOpKind entirely and having VisitUnaryPlus directly visit the subexpression with the appropriate promotion/demotion handling. --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 7 +- clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 34 ++--- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 26 ++-- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 11 +- .../Dialect/Transforms/LoweringPrepare.cpp | 1 - .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 24 +--- clang/lib/CodeGen/CGExprComplex.cpp | 135 +++++++++--------- clang/test/CIR/CodeGen/complex-unary.cpp | 36 ++--- clang/test/CIR/CodeGen/complex.cpp | 20 +-- clang/test/CIR/CodeGen/coro-task.cpp | 3 +- .../CIR/CodeGen/lambda-static-invoker.cpp | 3 +- clang/test/CIR/CodeGen/unary.cpp | 15 +- clang/test/CIR/CodeGen/vector-ext.cpp | 3 +- clang/test/CIR/CodeGen/vector.cpp | 3 +- clang/test/CIR/IR/unary.cir | 36 +++-- clang/test/CIR/Transforms/canonicalize.cir | 72 ---------- 16 files changed, 146 insertions(+), 283 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index d9c4356ba95b9..1ce458aed148f 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -1708,16 +1708,15 @@ def CIR_LabelOp : CIR_Op<"label", [AlwaysSpeculatable]> { def CIR_UnaryOpKind : CIR_I32EnumAttr<"UnaryOpKind", "unary operation kind", [ I32EnumAttrCase<"Inc", 0, "inc">, I32EnumAttrCase<"Dec", 1, "dec">, - I32EnumAttrCase<"Plus", 2, "plus">, - I32EnumAttrCase<"Minus", 3, "minus">, - I32EnumAttrCase<"Not", 4, "not"> + I32EnumAttrCase<"Minus", 2, "minus">, + I32EnumAttrCase<"Not", 3, "not"> ]>; def CIR_UnaryOp : CIR_Op<"unary", [Pure, SameOperandsAndResultType]> { let summary = "Unary operations"; let description = [{ `cir.unary` performs the unary operation according to - the specified opcode kind: [inc, dec, plus, minus, not]. + the specified opcode kind: [inc, dec, minus, not]. It requires one input operand and has one result, both types should be the same. diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 00d69cdf908f9..c68547e82d614 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -193,9 +193,9 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> { mlir::Value VisitUnaryDeref(const Expr *e) { return emitLoadOfLValue(e); } mlir::Value VisitUnaryPlus(const UnaryOperator *e); + mlir::Value VisitUnaryPlus(const UnaryOperator *e, QualType promotionType); mlir::Value VisitUnaryMinus(const UnaryOperator *e); - mlir::Value VisitPlusMinus(const UnaryOperator *e, cir::UnaryOpKind kind, - QualType promotionType); + mlir::Value VisitUnaryMinus(const UnaryOperator *e, QualType promotionType); mlir::Value VisitUnaryNot(const UnaryOperator *e); // LNot,Real,Imag never return complex. mlir::Value VisitUnaryExtension(const UnaryOperator *e) { @@ -573,32 +573,36 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op, mlir::Value ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *e) { QualType promotionTy = getPromotionType(e->getSubExpr()->getType()); - mlir::Value result = VisitPlusMinus(e, cir::UnaryOpKind::Plus, promotionTy); + mlir::Value result = VisitUnaryPlus(e, promotionTy); if (!promotionTy.isNull()) return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType()); return result; } +mlir::Value ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *e, + QualType promotionType) { + if (!promotionType.isNull()) + return cgf.emitPromotedComplexExpr(e->getSubExpr(), promotionType); + return Visit(e->getSubExpr()); +} + mlir::Value ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *e) { QualType promotionTy = getPromotionType(e->getSubExpr()->getType()); - mlir::Value result = VisitPlusMinus(e, cir::UnaryOpKind::Minus, promotionTy); + mlir::Value result = VisitUnaryMinus(e, promotionTy); if (!promotionTy.isNull()) return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType()); return result; } -mlir::Value ComplexExprEmitter::VisitPlusMinus(const UnaryOperator *e, - cir::UnaryOpKind kind, - QualType promotionType) { - assert((kind == cir::UnaryOpKind::Plus || kind == cir::UnaryOpKind::Minus) && - "Invalid UnaryOp kind for ComplexType Plus or Minus"); - +mlir::Value ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *e, + QualType promotionType) { mlir::Value op; if (!promotionType.isNull()) op = cgf.emitPromotedComplexExpr(e->getSubExpr(), promotionType); else op = Visit(e->getSubExpr()); - return builder.createUnaryOp(cgf.getLoc(e->getExprLoc()), kind, op); + return builder.createUnaryOp(cgf.getLoc(e->getExprLoc()), + cir::UnaryOpKind::Minus, op); } mlir::Value ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *e) { @@ -765,12 +769,10 @@ mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e, } } else if (const auto *unaryOp = dyn_cast<UnaryOperator>(e)) { switch (unaryOp->getOpcode()) { + case UO_Plus: + return VisitUnaryPlus(unaryOp, promotionTy); case UO_Minus: - case UO_Plus: { - auto kind = unaryOp->getOpcode() == UO_Plus ? cir::UnaryOpKind::Plus - : cir::UnaryOpKind::Minus; - return VisitPlusMinus(unaryOp, kind, promotionTy); - } + return VisitUnaryMinus(unaryOp, promotionTy); default: break; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 4a2973d3824ee..fa6e0c3a5fa36 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -766,25 +766,28 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { mlir::Value VisitUnaryPlus(const UnaryOperator *e) { QualType promotionType = getPromotionType(e->getSubExpr()->getType()); - mlir::Value result = - emitUnaryPlusOrMinus(e, cir::UnaryOpKind::Plus, promotionType); + mlir::Value result = VisitUnaryPlus(e, promotionType); if (result && !promotionType.isNull()) return emitUnPromotedValue(result, e->getType()); return result; } + mlir::Value VisitUnaryPlus(const UnaryOperator *e, QualType promotionType) { + ignoreResultAssign = false; + if (!promotionType.isNull()) + return cgf.emitPromotedScalarExpr(e->getSubExpr(), promotionType); + return Visit(e->getSubExpr()); + } + mlir::Value VisitUnaryMinus(const UnaryOperator *e) { QualType promotionType = getPromotionType(e->getSubExpr()->getType()); - mlir::Value result = - emitUnaryPlusOrMinus(e, cir::UnaryOpKind::Minus, promotionType); + mlir::Value result = VisitUnaryMinus(e, promotionType); if (result && !promotionType.isNull()) return emitUnPromotedValue(result, e->getType()); return result; } - mlir::Value emitUnaryPlusOrMinus(const UnaryOperator *e, - cir::UnaryOpKind kind, - QualType promotionType) { + mlir::Value VisitUnaryMinus(const UnaryOperator *e, QualType promotionType) { ignoreResultAssign = false; mlir::Value operand; if (!promotionType.isNull()) @@ -795,14 +798,13 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { // TODO(cir): We might have to change this to support overflow trapping. // Classic codegen routes unary minus through emitSub to ensure // that the overflow behavior is handled correctly. - bool nsw = kind == cir::UnaryOpKind::Minus && - e->getType()->isSignedIntegerType() && + bool nsw = e->getType()->isSignedIntegerType() && cgf.getLangOpts().getSignedOverflowBehavior() != LangOptions::SOB_Defined; // NOTE: LLVM codegen will lower this directly to either a FNeg // or a Sub instruction. In CIR this will be handled later in LowerToLLVM. - return emitUnaryOp(e, kind, operand, nsw); + return emitUnaryOp(e, cir::UnaryOpKind::Minus, operand, nsw); } mlir::Value emitUnaryOp(const UnaryOperator *e, cir::UnaryOpKind kind, @@ -1566,9 +1568,9 @@ mlir::Value ScalarExprEmitter::emitPromoted(const Expr *e, case UO_Real: return VisitRealImag(uo, promotionType); case UO_Minus: - return emitUnaryPlusOrMinus(uo, cir::UnaryOpKind::Minus, promotionType); + return VisitUnaryMinus(uo, promotionType); case UO_Plus: - return emitUnaryPlusOrMinus(uo, cir::UnaryOpKind::Plus, promotionType); + return VisitUnaryPlus(uo, promotionType); default: break; } diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 8d2990af5de8c..87cf3950b04d6 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2671,7 +2671,6 @@ LogicalResult cir::UnaryOp::verify() { switch (getKind()) { case cir::UnaryOpKind::Inc: case cir::UnaryOpKind::Dec: - case cir::UnaryOpKind::Plus: case cir::UnaryOpKind::Minus: case cir::UnaryOpKind::Not: // Nothing to verify. @@ -2712,9 +2711,8 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) { // input attribute from the adapter, a new constant is materialized, but // if we return the input value directly, it avoids that. if (auto srcConst = getInput().getDefiningOp<cir::ConstantOp>()) { - if (getKind() == cir::UnaryOpKind::Plus || - (mlir::isa<cir::BoolType>(srcConst.getType()) && - getKind() == cir::UnaryOpKind::Minus)) + if (mlir::isa<cir::BoolType>(srcConst.getType()) && + getKind() == cir::UnaryOpKind::Minus) return srcConst.getResult(); } @@ -2733,8 +2731,6 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) { val.flipAllBits(); return cir::IntAttr::get(getType(), val); } - case cir::UnaryOpKind::Plus: - return attrT; case cir::UnaryOpKind::Minus: { APInt val = attrT.getValue(); val.negate(); @@ -2746,8 +2742,6 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) { }) .Case<cir::FPAttr>([&](cir::FPAttr attrT) { switch (getKind()) { - case cir::UnaryOpKind::Plus: - return attrT; case cir::UnaryOpKind::Minus: { APFloat val = attrT.getValue(); val.changeSign(); @@ -2761,7 +2755,6 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) { switch (getKind()) { case cir::UnaryOpKind::Not: return cir::BoolAttr::get(getContext(), !attrT.getValue()); - case cir::UnaryOpKind::Plus: case cir::UnaryOpKind::Minus: return attrT; default: diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index 82bf8dbccba97..500f45ba9c567 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -822,7 +822,6 @@ void LoweringPreparePass::lowerUnaryOp(cir::UnaryOp op) { resultImag = operandImag; break; - case cir::UnaryOpKind::Plus: case cir::UnaryOpKind::Minus: resultReal = builder.createUnaryOp(loc, opKind, operandReal); resultImag = builder.createUnaryOp(loc, opKind, operandImag); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 8f80b1ee5116e..d610c68b694b4 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -2742,7 +2742,7 @@ mlir::LogicalResult CIRToLLVMUnaryOpLowering::matchAndRewrite( mlir::Type llvmType = getTypeConverter()->convertType(type); mlir::Location loc = op.getLoc(); - // Integer unary operations: + - ~ ++ -- + // Integer unary operations: - ~ ++ -- if (mlir::isa<cir::IntType>(elementType)) { mlir::LLVM::IntegerOverflowFlags maybeNSW = op.getNoSignedWrap() ? mlir::LLVM::IntegerOverflowFlags::nsw @@ -2762,9 +2762,6 @@ mlir::LogicalResult CIRToLLVMUnaryOpLowering::matchAndRewrite( one, maybeNSW); return mlir::success(); } - case cir::UnaryOpKind::Plus: - rewriter.replaceOp(op, adaptor.getInput()); - return mlir::success(); case cir::UnaryOpKind::Minus: { mlir::Value zero; if (isVector) @@ -2796,7 +2793,7 @@ mlir::LogicalResult CIRToLLVMUnaryOpLowering::matchAndRewrite( llvm_unreachable("Unexpected unary op for int"); } - // Floating point unary operations: + - ++ -- + // Floating point unary operations: - ++ -- if (mlir::isa<cir::FPTypeInterface>(elementType)) { switch (op.getKind()) { case cir::UnaryOpKind::Inc: { @@ -2815,9 +2812,6 @@ mlir::LogicalResult CIRToLLVMUnaryOpLowering::matchAndRewrite( adaptor.getInput()); return mlir::success(); } - case cir::UnaryOpKind::Plus: - rewriter.replaceOp(op, adaptor.getInput()); - return mlir::success(); case cir::UnaryOpKind::Minus: rewriter.replaceOpWithNewOp<mlir::LLVM::FNegOp>(op, llvmType, adaptor.getInput()); @@ -2834,7 +2828,6 @@ mlir::LogicalResult CIRToLLVMUnaryOpLowering::matchAndRewrite( switch (op.getKind()) { case cir::UnaryOpKind::Inc: case cir::UnaryOpKind::Dec: - case cir::UnaryOpKind::Plus: case cir::UnaryOpKind::Minus: // Some of these are allowed in source code, but we shouldn't get here // with a boolean type. @@ -2850,19 +2843,6 @@ mlir::LogicalResult CIRToLLVMUnaryOpLowering::matchAndRewrite( llvm_unreachable("Unexpected unary op for bool"); } - // Pointer unary operations: + only. (++ and -- of pointers are implemented - // with cir.ptr_stride, not cir.unary.) - if (mlir::isa<cir::PointerType>(elementType)) { - switch (op.getKind()) { - case cir::UnaryOpKind::Plus: - rewriter.replaceOp(op, adaptor.getInput()); - return mlir::success(); - default: - op.emitError() << "Unknown pointer unary operation during CIR lowering"; - return mlir::failure(); - } - } - return op.emitError() << "Unary operation has unsupported type: " << elementType; } diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 54f18064c8cbc..92129a041fd8e 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -39,9 +39,9 @@ static const ComplexType *getComplexType(QualType type) { } } -namespace { +namespace { class ComplexExprEmitter - : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> { + : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> { CodeGenFunction &CGF; CGBuilderTy &Builder; bool IgnoreReal; @@ -108,7 +108,9 @@ class ComplexExprEmitter Result->getAggregateElement(1U)); return Visit(E->getSubExpr()); } - ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} + ComplexPairTy VisitParenExpr(ParenExpr *PE) { + return Visit(PE->getSubExpr()); + } ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) { return Visit(GE->getResultExpr()); } @@ -185,15 +187,15 @@ class ComplexExprEmitter if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E)) CGF.CGM.EmitExplicitCastExprType(ECE, &CGF); if (E->changesVolatileQualification()) - return EmitLoadOfLValue(E); + return EmitLoadOfLValue(E); return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); } ComplexPairTy VisitCallExpr(const CallExpr *E); ComplexPairTy VisitStmtExpr(const StmtExpr *E); // Operators. - ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E, - bool isInc, bool isPre) { + ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E, bool isInc, + bool isPre) { LValue LV = CGF.EmitLValue(E->getSubExpr()); return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre); } @@ -217,7 +219,7 @@ class ComplexExprEmitter ComplexPairTy VisitUnaryMinus(const UnaryOperator *E, QualType PromotionType = QualType()); ComplexPairTy VisitMinus(const UnaryOperator *E, QualType PromotionType); - ComplexPairTy VisitUnaryNot (const UnaryOperator *E); + ComplexPairTy VisitUnaryNot(const UnaryOperator *E); // LNot,Real,Imag never return complex. ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) { return Visit(E->getSubExpr()); @@ -247,15 +249,14 @@ class ComplexExprEmitter ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { assert(E->getType()->isAnyComplexType() && "Expected complex type!"); QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); - llvm::Constant *Null = - llvm::Constant::getNullValue(CGF.ConvertType(Elem)); + llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); return ComplexPairTy(Null, Null); } struct BinOpInfo { ComplexPairTy LHS; ComplexPairTy RHS; - QualType Ty; // Computation Type. + QualType Ty; // Computation Type. FPOptions FPFeatures; }; @@ -263,13 +264,13 @@ class ComplexExprEmitter QualType PromotionTy = QualType()); ComplexPairTy EmitPromoted(const Expr *E, QualType PromotionTy); ComplexPairTy EmitPromotedComplexOperand(const Expr *E, QualType PromotionTy); - LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, - ComplexPairTy (ComplexExprEmitter::*Func) - (const BinOpInfo &), - RValue &Val); - ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E, - ComplexPairTy (ComplexExprEmitter::*Func) - (const BinOpInfo &)); + LValue EmitCompoundAssignLValue( + const CompoundAssignOperator *E, + ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo &), + RValue &Val); + ComplexPairTy EmitCompoundAssign( + const CompoundAssignOperator *E, + ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo &)); ComplexPairTy EmitBinAdd(const BinOpInfo &Op); ComplexPairTy EmitBinSub(const BinOpInfo &Op); @@ -381,11 +382,9 @@ class ComplexExprEmitter // No comparisons produce a complex result. - LValue EmitBinAssignLValue(const BinaryOperator *E, - ComplexPairTy &Val); - ComplexPairTy VisitBinAssign (const BinaryOperator *E); - ComplexPairTy VisitBinComma (const BinaryOperator *E); - + LValue EmitBinAssignLValue(const BinaryOperator *E, ComplexPairTy &Val); + ComplexPairTy VisitBinAssign(const BinaryOperator *E); + ComplexPairTy VisitBinComma(const BinaryOperator *E); ComplexPairTy VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO); @@ -407,7 +406,7 @@ class ComplexExprEmitter return Visit(E->getSelectedExpr()); } }; -} // end anonymous namespace. +} // end anonymous namespace. //===----------------------------------------------------------------------===// // Utilities @@ -469,8 +468,6 @@ void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue, CGF.addInstToCurrentSourceAtom(I, Val.second); } - - //===----------------------------------------------------------------------===// // Visitor Methods //===----------------------------------------------------------------------===// @@ -478,18 +475,17 @@ void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue, ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) { CGF.ErrorUnsupported(E, "complex expression"); llvm::Type *EltTy = - CGF.ConvertType(getComplexType(E->getType())->getElementType()); + CGF.ConvertType(getComplexType(E->getType())->getElementType()); llvm::Value *U = llvm::PoisonValue::get(EltTy); return ComplexPairTy(U, U); } -ComplexPairTy ComplexExprEmitter:: -VisitImaginaryLiteral(const ImaginaryLiteral *IL) { +ComplexPairTy +ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *IL) { llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr()); return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag); } - ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) { if (E->getCallReturnType(CGF.getContext())->isReferenceType()) return EmitLoadOfLValue(E); @@ -539,7 +535,8 @@ ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val, ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op, QualType DestTy) { switch (CK) { - case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!"); + case CK_Dependent: + llvm_unreachable("dependent cast kind in IR gen!"); // Atomic to non-atomic casts may be more than a no-op for some platforms and // for some types. @@ -691,10 +688,10 @@ ComplexPairTy ComplexExprEmitter::VisitMinus(const UnaryOperator *E, llvm::Value *ResR, *ResI; if (Op.first->getType()->isFloatingPointTy()) { - ResR = Builder.CreateFNeg(Op.first, "neg.r"); + ResR = Builder.CreateFNeg(Op.first, "neg.r"); ResI = Builder.CreateFNeg(Op.second, "neg.i"); } else { - ResR = Builder.CreateNeg(Op.first, "neg.r"); + ResR = Builder.CreateNeg(Op.first, "neg.r"); ResI = Builder.CreateNeg(Op.second, "neg.i"); } return ComplexPairTy(ResR, ResI); @@ -719,14 +716,14 @@ ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) { if (Op.LHS.first->getType()->isFloatingPointTy()) { CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); - ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r"); + ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r"); if (Op.LHS.second && Op.RHS.second) ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i"); else ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second; assert(ResI && "Only one operand may be real!"); } else { - ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r"); + ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r"); assert(Op.LHS.second && Op.RHS.second && "Both operands of integer complex operators must be complex!"); ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i"); @@ -884,11 +881,13 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { // Finally continue execution by phi-ing together the different // computation paths. CGF.EmitBlock(ContBB); - llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->getType(), 3, "real_mul_phi"); + llvm::PHINode *RealPHI = + Builder.CreatePHI(ResR->getType(), 3, "real_mul_phi"); RealPHI->addIncoming(ResR, OrigBB); RealPHI->addIncoming(ResR, INaNBB); RealPHI->addIncoming(LibCallR, LibCallBB); - llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->getType(), 3, "imag_mul_phi"); + llvm::PHINode *ImagPHI = + Builder.CreatePHI(ResI->getType(), 3, "imag_mul_phi"); ImagPHI->addIncoming(ResI, OrigBB); ImagPHI->addIncoming(ResI, INaNBB); ImagPHI->addIncoming(LibCallI, LibCallBB); @@ -1097,7 +1096,9 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad - if (Op.Ty->castAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) { + if (Op.Ty->castAs<ComplexType>() + ->getElementType() + ->isUnsignedIntegerType()) { DSTr = Builder.CreateUDiv(Tmp3, Tmp6); DSTi = Builder.CreateUDiv(Tmp9, Tmp6); } else { @@ -1209,11 +1210,9 @@ ComplexExprEmitter::EmitBinOps(const BinaryOperator *E, return Ops; } - -LValue ComplexExprEmitter:: -EmitCompoundAssignLValue(const CompoundAssignOperator *E, - ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&), - RValue &Val) { +LValue ComplexExprEmitter::EmitCompoundAssignLValue( + const CompoundAssignOperator *E, + ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo &), RValue &Val) { TestAndClearIgnoreReal(); TestAndClearIgnoreImag(); QualType LHSTy = E->getLHS()->getType(); @@ -1323,9 +1322,9 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E, } // Compound assignments. -ComplexPairTy ComplexExprEmitter:: -EmitCompoundAssign(const CompoundAssignOperator *E, - ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){ +ComplexPairTy ComplexExprEmitter::EmitCompoundAssign( + const CompoundAssignOperator *E, + ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo &)) { RValue Val; LValue LV = EmitCompoundAssignLValue(E, Func, Val); @@ -1381,8 +1380,8 @@ ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { return Visit(E->getRHS()); } -ComplexPairTy ComplexExprEmitter:: -VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { +ComplexPairTy ComplexExprEmitter::VisitAbstractConditionalOperator( + const AbstractConditionalOperator *E) { TestAndClearIgnoreReal(); TestAndClearIgnoreImag(); llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); @@ -1392,7 +1391,6 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { // Bind the common expression if necessary. CodeGenFunction::OpaqueValueMapping binding(CGF, E); - CodeGenFunction::ConditionalEvaluation eval(CGF); CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock, CGF.getProfileCount(E)); @@ -1431,12 +1429,12 @@ ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) { } ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { - bool Ignore = TestAndClearIgnoreReal(); - (void)Ignore; - assert (Ignore == false && "init list ignored"); - Ignore = TestAndClearIgnoreImag(); - (void)Ignore; - assert (Ignore == false && "init list ignored"); + bool Ignore = TestAndClearIgnoreReal(); + (void)Ignore; + assert(Ignore == false && "init list ignored"); + Ignore = TestAndClearIgnoreImag(); + (void)Ignore; + assert(Ignore == false && "init list ignored"); if (E->getNumInits() == 2) { llvm::Value *Real = CGF.EmitScalarExpr(E->getInit(0)); @@ -1449,8 +1447,8 @@ ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { // Empty init list initializes to null assert(E->getNumInits() == 0 && "Unexpected number of inits"); QualType Ty = E->getType()->castAs<ComplexType>()->getElementType(); - llvm::Type* LTy = CGF.ConvertType(Ty); - llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy); + llvm::Type *LTy = CGF.ConvertType(Ty); + llvm::Value *zeroConstant = llvm::Constant::getNullValue(LTy); return ComplexPairTy(zeroConstant, zeroConstant); } @@ -1461,7 +1459,7 @@ ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { if (!ArgValue.isValid()) { CGF.ErrorUnsupported(E, "complex va_arg expression"); llvm::Type *EltTy = - CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType()); + CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType()); llvm::Value *U = llvm::PoisonValue::get(EltTy); return ComplexPairTy(U, U); } @@ -1489,7 +1487,7 @@ void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest, assert(E && getComplexType(E->getType()) && "Invalid complex expression to emit"); ComplexExprEmitter Emitter(*this); - ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E)); + ComplexPairTy Val = Emitter.Visit(const_cast<Expr *>(E)); Emitter.EmitStoreOfComplex(Val, dest, isInit); } @@ -1520,26 +1518,29 @@ typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)( static CompoundFunc getComplexOp(BinaryOperatorKind Op) { switch (Op) { - case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul; - case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv; - case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub; - case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd; + case BO_MulAssign: + return &ComplexExprEmitter::EmitBinMul; + case BO_DivAssign: + return &ComplexExprEmitter::EmitBinDiv; + case BO_SubAssign: + return &ComplexExprEmitter::EmitBinSub; + case BO_AddAssign: + return &ComplexExprEmitter::EmitBinAdd; default: llvm_unreachable("unexpected complex compound assignment"); } } -LValue CodeGenFunction:: -EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) { +LValue CodeGenFunction::EmitComplexCompoundAssignmentLValue( + const CompoundAssignOperator *E) { ApplyAtomGroup Grp(getDebugInfo()); CompoundFunc Op = getComplexOp(E->getOpcode()); RValue Val; return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); } -LValue CodeGenFunction:: -EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, - llvm::Value *&Result) { +LValue CodeGenFunction::EmitScalarCompoundAssignWithComplex( + const CompoundAssignOperator *E, llvm::Value *&Result) { // Key Instructions: Don't need to create an atom group here; one will already // be active through scalar handling code. CompoundFunc Op = getComplexOp(E->getOpcode()); diff --git a/clang/test/CIR/CodeGen/complex-unary.cpp b/clang/test/CIR/CodeGen/complex-unary.cpp index a8e434b903763..31cc0d8b8de56 100644 --- a/clang/test/CIR/CodeGen/complex-unary.cpp +++ b/clang/test/CIR/CodeGen/complex-unary.cpp @@ -293,27 +293,19 @@ void foo7() { // CIR-BEFORE: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"] // CIR-BEFORE: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init] // CIR-BEFORE: %[[TMP:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR-BEFORE: %[[COMPLEX_PLUS:.*]] = cir.unary(plus, %[[TMP]]) : !cir.complex<!cir.float>, !cir.complex<!cir.float> -// CIR-BEFORE: cir.store{{.*}} %[[COMPLEX_PLUS]], %[[B_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>> +// CIR-BEFORE-NOT: cir.unary +// CIR-BEFORE: cir.store{{.*}} %[[TMP]], %[[B_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>> // CIR-AFTER: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"] // CIR-AFTER: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init] // CIR-AFTER: %[[TMP:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR-AFTER: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex<!cir.float> -> !cir.float -// CIR-AFTER: %[[IMAG:.*]] = cir.complex.imag %[[TMP]] : !cir.complex<!cir.float> -> !cir.float -// CIR-AFTER: %[[REAL_PLUS:.*]] = cir.unary(plus, %[[REAL]]) : !cir.float, !cir.float -// CIR-AFTER: %[[IMAG_PLUS:.*]] = cir.unary(plus, %[[IMAG]]) : !cir.float, !cir.float -// CIR-AFTER: %[[NEW_COMPLEX:.*]] = cir.complex.create %[[REAL_PLUS]], %[[IMAG_PLUS]] : !cir.float -> !cir.complex<!cir.float> -// CIR-AFTER: cir.store{{.*}} %[[NEW_COMPLEX]], %[[B_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>> +// CIR-AFTER-NOT: cir.unary +// CIR-AFTER: cir.store{{.*}} %[[TMP]], %[[B_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>> // LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 4 // LLVM: %[[B_ADDR:.*]] = alloca { float, float }, i64 1, align 4 // LLVM: %[[TMP:.*]] = load { float, float }, ptr %[[A_ADDR]], align 4 -// LLVM: %[[REAL:.*]] = extractvalue { float, float } %[[TMP]], 0 -// LLVM: %[[IMAG:.*]] = extractvalue { float, float } %[[TMP]], 1 -// LLVM: %[[RESULT_TMP:.*]] = insertvalue { float, float } {{.*}}, float %[[REAL]], 0 -// LLVM: %[[RESULT_VAL:.*]] = insertvalue { float, float } %[[RESULT_TMP]], float %[[IMAG]], 1 -// LLVM: store { float, float } %[[RESULT_VAL]], ptr %[[B_ADDR]], align 4 +// LLVM: store { float, float } %[[TMP]], ptr %[[B_ADDR]], align 4 // OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4 // OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 4 @@ -381,8 +373,8 @@ void foo9() { // CIR-BEFORE: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>>, ["b", init] // CIR-BEFORE: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.f16>>, !cir.complex<!cir.f16> // CIR-BEFORE: %[[A_COMPLEX_F32:.*]] = cir.cast float_complex %[[TMP_A]] : !cir.complex<!cir.f16> -> !cir.complex<!cir.float> -// CIR-BEFORE: %[[RESULT:.*]] = cir.unary(plus, %[[A_COMPLEX_F32]]) : !cir.complex<!cir.float>, !cir.complex<!cir.float> -// CIR-BEFORE: %[[A_COMPLEX_F16:.*]] = cir.cast float_complex %[[RESULT]] : !cir.complex<!cir.float> -> !cir.complex<!cir.f16> +// CIR-BEFORE-NOT: cir.unary +// CIR-BEFORE: %[[A_COMPLEX_F16:.*]] = cir.cast float_complex %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.complex<!cir.f16> // CIR-BEFORE: cir.store{{.*}} %[[A_COMPLEX_F16]], %[[B_ADDR]] : !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>> // CIR-AFTER: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.f16>, !cir.ptr<!cir.complex<!cir.f16>>, ["a"] @@ -393,13 +385,9 @@ void foo9() { // CIR-AFTER: %[[A_REAL_F32:.*]] = cir.cast floating %[[A_REAL]] : !cir.f16 -> !cir.float // CIR-AFTER: %[[A_IMAG_F32:.*]] = cir.cast floating %[[A_IMAG]] : !cir.f16 -> !cir.float // CIR-AFTER: %[[A_COMPLEX_F32:.*]] = cir.complex.create %[[A_REAL_F32]], %[[A_IMAG_F32]] : !cir.float -> !cir.complex<!cir.float> -// CIR-AFTER: %[[A_REAL_F32:.*]] = cir.complex.real %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float -// CIR-AFTER: %[[A_IMAG_F32:.*]] = cir.complex.imag %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float -// CIR-AFTER: %[[RESULT_REAL_F32:.*]] = cir.unary(plus, %[[A_REAL_F32]]) : !cir.float, !cir.float -// CIR-AFTER: %[[RESULT_IMAG_F32:.*]] = cir.unary(plus, %[[A_IMAG_F32]]) : !cir.float, !cir.float -// CIR-AFTER: %[[RESULT_COMPLEX_F32:.*]] = cir.complex.create %[[RESULT_REAL_F32]], %[[RESULT_IMAG_F32]] : !cir.float -> !cir.complex<!cir.float> -// CIR-AFTER: %[[RESULT_REAL_F32:.*]] = cir.complex.real %[[RESULT_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float -// CIR-AFTER: %[[RESULT_IMAG_F32:.*]] = cir.complex.imag %[[RESULT_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER: %[[RESULT_REAL_F32:.*]] = cir.complex.real %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER: %[[RESULT_IMAG_F32:.*]] = cir.complex.imag %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> -> !cir.float +// CIR-AFTER-NOT: cir.unary // CIR-AFTER: %[[RESULT_REAL_F16:.*]] = cir.cast floating %[[RESULT_REAL_F32]] : !cir.float -> !cir.f16 // CIR-AFTER: %[[RESULT_IMAG_F16:.*]] = cir.cast floating %[[RESULT_IMAG_F32]] : !cir.float -> !cir.f16 // CIR-AFTER: %[[RESULT_COMPLEX_F16:.*]] = cir.complex.create %[[RESULT_REAL_F16]], %[[RESULT_IMAG_F16]] : !cir.f16 -> !cir.complex<!cir.f16> @@ -412,10 +400,6 @@ void foo9() { // LLVM: %[[A_IMAG:.*]] = extractvalue { half, half } %[[TMP_A]], 1 // LLVM: %[[A_REAL_F32:.*]] = fpext half %[[A_REAL]] to float // LLVM: %[[A_IMAG_F32:.*]] = fpext half %[[A_IMAG]] to float -// LLVM: %[[TMP_A_COMPLEX_F32:.*]] = insertvalue { float, float } {{.*}}, float %[[A_REAL_F32]], 0 -// LLVM: %[[A_COMPLEX_F32:.*]] = insertvalue { float, float } %[[TMP_A_COMPLEX_F32]], float %[[A_IMAG_F32]], 1 -// LLVM: %[[TMP_A_COMPLEX_F32:.*]] = insertvalue { float, float } {{.*}}, float %[[A_REAL_F32]], 0 -// LLVM: %[[A_COMPLEX_F32:.*]] = insertvalue { float, float } %[[TMP_A_COMPLEX_F32]], float %[[A_IMAG_F32]], 1 // LLVM: %[[A_REAL_F16:.*]] = fptrunc float %[[A_REAL_F32]] to half // LLVM: %[[A_IMAG_F16:.*]] = fptrunc float %[[A_IMAG_F32]] to half // LLVM: %[[TMP_RESULT_COMPLEX_F16:.*]] = insertvalue { half, half } {{.*}}, half %[[A_REAL_F16]], 0 diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index d91083f0513cc..f65f0eea7fbaa 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -1034,21 +1034,13 @@ void real_on_non_glvalue() { // CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"] // CIR: %[[B_ADDR:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["b", init] // CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR: %[[A_REAL:.*]] = cir.complex.real %[[TMP_A]] : !cir.complex<!cir.float> -> !cir.float -// CIR: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.complex<!cir.float> -> !cir.float -// CIR: %[[A_REAL_PLUS:.*]] = cir.unary(plus, %[[A_REAL]]) : !cir.float, !cir.float -// CIR: %[[A_IMAG_PLUS:.*]] = cir.unary(plus, %[[A_IMAG]]) : !cir.float, !cir.float -// CIR: %[[RESULT:.*]] = cir.complex.create %[[A_REAL_PLUS]], %[[A_IMAG_PLUS]] : !cir.float -> !cir.complex<!cir.float> -// CIR: %[[RESULT_REAL:.*]] = cir.complex.real %[[RESULT]] : !cir.complex<!cir.float> -> !cir.float +// CIR: %[[RESULT_REAL:.*]] = cir.complex.real %[[TMP_A]] : !cir.complex<!cir.float> -> !cir.float // CIR: cir.store{{.*}} %[[RESULT_REAL]], %[[B_ADDR]] : !cir.float, !cir.ptr<!cir.float> // LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 4 // LLVM: %[[B_ADDR:.*]] = alloca float, i64 1, align 4 // LLVM: %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 4 // LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[TMP_A]], 0 -// LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[TMP_A]], 1 -// LLVM: %[[TMP_RESULT:.*]] = insertvalue { float, float } {{.*}}, float %[[A_REAL]], 0 -// LLVM: %[[RESULT:.*]] = insertvalue { float, float } %[[TMP_RESULT]], float %[[A_IMAG]], 1 // LLVM: store float %[[A_REAL]], ptr %[[B_ADDR]], align 4 // OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4 @@ -1067,21 +1059,13 @@ void imag_on_non_glvalue() { // CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"] // CIR: %[[B_ADDR:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["b", init] // CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR: %[[A_REAL:.*]] = cir.complex.real %[[TMP_A]] : !cir.complex<!cir.float> -> !cir.float -// CIR: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.complex<!cir.float> -> !cir.float -// CIR: %[[A_REAL_PLUS:.*]] = cir.unary(plus, %[[A_REAL]]) : !cir.float, !cir.float -// CIR: %[[A_IMAG_PLUS:.*]] = cir.unary(plus, %[[A_IMAG]]) : !cir.float, !cir.float -// CIR: %[[RESULT:.*]] = cir.complex.create %[[A_REAL_PLUS]], %[[A_IMAG_PLUS]] : !cir.float -> !cir.complex<!cir.float> -// CIR: %[[RESULT_IMAG:.*]] = cir.complex.imag %[[RESULT]] : !cir.complex<!cir.float> -> !cir.float +// CIR: %[[RESULT_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.complex<!cir.float> -> !cir.float // CIR: cir.store{{.*}} %[[RESULT_IMAG]], %[[B_ADDR]] : !cir.float, !cir.ptr<!cir.float> // LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 4 // LLVM: %[[B_ADDR:.*]] = alloca float, i64 1, align 4 // LLVM: %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 4 -// LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[TMP_A]], 0 // LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[TMP_A]], 1 -// LLVM: %[[TMP_RESULT:.*]] = insertvalue { float, float } {{.*}}, float %[[A_REAL]], 0 -// LLVM: %[[RESULT:.*]] = insertvalue { float, float } %[[TMP_RESULT]], float %[[A_IMAG]], 1 // LLVM: store float %[[A_IMAG]], ptr %[[B_ADDR]], align 4 // OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4 diff --git a/clang/test/CIR/CodeGen/coro-task.cpp b/clang/test/CIR/CodeGen/coro-task.cpp index 637b058443bc7..b52f0f1871079 100644 --- a/clang/test/CIR/CodeGen/coro-task.cpp +++ b/clang/test/CIR/CodeGen/coro-task.cpp @@ -569,8 +569,7 @@ folly::coro::Task<int> go4() { // Get the lambda invoker ptr via `lambda operator folly::coro::Task<int> (*)(int const&)()` // CIR: %[[INVOKER:.*]] = cir.call @_ZZ3go4vENK3$_0cvPFN5folly4coro4TaskIiEERKiEEv(%{{.*}}) nothrow : {{.*}} -> (!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>> {llvm.noundef}) -// CIR: %[[PLUS:.*]] = cir.unary(plus, %[[INVOKER]]) : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>> -// CIR: cir.store{{.*}} %[[PLUS]], %[[FN_ADDR:.*]] : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>> +// CIR: cir.store{{.*}} %[[INVOKER]], %[[FN_ADDR:.*]] : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>> // CIR: cir.scope { // CIR: %[[ARG:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["ref.tmp2", init] {alignment = 4 : i64} // CIR: %[[FN:.*]] = cir.load{{.*}} %[[FN_ADDR]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>>, !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>> diff --git a/clang/test/CIR/CodeGen/lambda-static-invoker.cpp b/clang/test/CIR/CodeGen/lambda-static-invoker.cpp index 2b00feccbc79a..25c17d6b37dde 100644 --- a/clang/test/CIR/CodeGen/lambda-static-invoker.cpp +++ b/clang/test/CIR/CodeGen/lambda-static-invoker.cpp @@ -121,10 +121,9 @@ int g3() { // 1. Use `operator int (*)(int const&)()` to retrieve the fnptr to `__invoke()`. // CIR: %[[OPERATOR_RESULT:.*]] = cir.call @_ZZ2g3vENK3$_0cvPFiRKiEEv(%[[LAM_ALLOCA]]){{.*}} -// CIR: %[[PLUS:.*]] = cir.unary(plus, %[[OPERATOR_RESULT]]) // 2. Load ptr to `__invoke()`. -// CIR: cir.store{{.*}} %[[PLUS]], %[[FN_ADDR]] +// CIR: cir.store{{.*}} %[[OPERATOR_RESULT]], %[[FN_ADDR]] // CIR: %[[FN:.*]] = cir.load{{.*}} %[[FN_ADDR]] // CIR: %[[THREE:.*]] = cir.const #cir.int<3> : !s32i // CIR: cir.store{{.*}} %[[THREE]], %[[REF_TMP1]] diff --git a/clang/test/CIR/CodeGen/unary.cpp b/clang/test/CIR/CodeGen/unary.cpp index cc6f2ade38f3f..7d4c8f27e4545 100644 --- a/clang/test/CIR/CodeGen/unary.cpp +++ b/clang/test/CIR/CodeGen/unary.cpp @@ -13,7 +13,7 @@ unsigned up0() { // CHECK: cir.func{{.*}} @_Z3up0v() -> (!u32i{{.*}}) // CHECK: %[[A:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init] // CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]] -// CHECK: %[[OUTPUT:.*]] = cir.unary(plus, %[[INPUT]]) +// CHECK-NOT: cir.unary // LLVM: define{{.*}} i32 @_Z3up0v() // LLVM: %[[RV:.*]] = alloca i32, i64 1, align 4 @@ -231,7 +231,7 @@ float fpPlus() { // CHECK: cir.func{{.*}} @_Z6fpPlusv() -> (!cir.float{{.*}}) // CHECK: %[[A:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a", init] // CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]] -// CHECK: %[[OUTPUT:.*]] = cir.unary(plus, %[[INPUT]]) +// CHECK-NOT: cir.unary // LLVM: define{{.*}} float @_Z6fpPlusv() // LLVM: %[[RV:.*]] = alloca float, i64 1, align 4 @@ -411,7 +411,7 @@ void chars(char c) { int c1 = +c; // CHECK: %[[PROMO:.*]] = cir.cast integral %{{.+}} : !s8i -> !s32i - // CHECK: cir.unary(plus, %[[PROMO]]) : !s32i, !s32i + // CHECK-NOT: cir.unary int c2 = -c; // CHECK: %[[PROMO:.*]] = cir.cast integral %{{.+}} : !s8i -> !s32i // CHECK: cir.unary(minus, %[[PROMO]]) nsw : !s32i, !s32i @@ -432,8 +432,8 @@ _Float16 fp16UPlus(_Float16 f) { // CHECK: cir.func{{.*}} @_Z9fp16UPlusDF16_({{.*}}) -> (!cir.f16{{.*}}) // CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[F:.*]] // CHECK: %[[PROMOTED:.*]] = cir.cast floating %[[INPUT]] : !cir.f16 -> !cir.float -// CHECK: %[[RESULT:.*]] = cir.unary(plus, %[[PROMOTED]]) -// CHECK: %[[UNPROMOTED:.*]] = cir.cast floating %[[RESULT]] : !cir.float -> !cir.f16 +// CHECK-NOT: cir.unary +// CHECK: %[[UNPROMOTED:.*]] = cir.cast floating %[[PROMOTED]] : !cir.float -> !cir.f16 // LLVM: define{{.*}} half @_Z9fp16UPlusDF16_({{.*}}) // LLVM: %[[F_LOAD:.*]] = load half, ptr %{{.*}}, align 2 @@ -567,9 +567,8 @@ void f16NestedUPlus() { // CHECK: %[[B_ADDR:.*]] = cir.alloca !cir.f16, !cir.ptr<!cir.f16>, ["b", init] // CHECK: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.f16>, !cir.f16 // CHECK: %[[A_F32:.*]] = cir.cast floating %[[TMP_A]] : !cir.f16 -> !cir.float -// CHECK: %[[A_PLUS:.*]] = cir.unary(plus, %[[A_F32]]) : !cir.float, !cir.float -// CHECK: %[[RESULT_F32:.*]] = cir.unary(plus, %[[A_PLUS]]) : !cir.float, !cir.float -// CHECK: %[[RESULT:.*]] = cir.cast floating %[[RESULT_F32]] : !cir.float -> !cir.f16 +// CHECK-NOT: cir.unary +// CHECK: %[[RESULT:.*]] = cir.cast floating %[[A_F32]] : !cir.float -> !cir.f16 // CHECK: cir.store{{.*}} %[[RESULT]], %[[B_ADDR]] : !cir.f16, !cir.ptr<!cir.f16> // LLVM: define{{.*}} void @_Z14f16NestedUPlusv() diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp index e7d6b4974c6ae..a32bc94bae103 100644 --- a/clang/test/CIR/CodeGen/vector-ext.cpp +++ b/clang/test/CIR/CodeGen/vector-ext.cpp @@ -332,8 +332,7 @@ void foo8() { // CIR-SAME: #cir.int<3> : !s32i, #cir.int<4> : !s32i]> : !cir.vector<4 x !s32i> // CIR: cir.store{{.*}} %[[VEC_VAL]], %[[VEC]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> // CIR: %[[TMP1:.*]] = cir.load{{.*}} %[[VEC]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> -// CIR: %[[PLUS:.*]] = cir.unary(plus, %[[TMP1]]) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> -// CIR: cir.store{{.*}} %[[PLUS]], %[[PLUS_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> +// CIR: cir.store{{.*}} %[[TMP1]], %[[PLUS_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> // CIR: %[[TMP2:.*]] = cir.load{{.*}} %[[VEC]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> // CIR: %[[MINUS:.*]] = cir.unary(minus, %[[TMP2]]) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> // CIR: cir.store{{.*}} %[[MINUS]], %[[MINUS_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> diff --git a/clang/test/CIR/CodeGen/vector.cpp b/clang/test/CIR/CodeGen/vector.cpp index 8a804ad6fa2f1..26b4e4a8f7f8a 100644 --- a/clang/test/CIR/CodeGen/vector.cpp +++ b/clang/test/CIR/CodeGen/vector.cpp @@ -319,8 +319,7 @@ void foo8() { // CIR-SAME: #cir.int<3> : !s32i, #cir.int<4> : !s32i]> : !cir.vector<4 x !s32i> // CIR: cir.store{{.*}} %[[VEC_VAL]], %[[VEC]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> // CIR: %[[TMP1:.*]] = cir.load{{.*}} %[[VEC]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> -// CIR: %[[PLUS:.*]] = cir.unary(plus, %[[TMP1]]) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> -// CIR: cir.store{{.*}} %[[PLUS]], %[[PLUS_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> +// CIR: cir.store{{.*}} %[[TMP1]], %[[PLUS_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> // CIR: %[[TMP2:.*]] = cir.load{{.*}} %[[VEC]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> // CIR: %[[MINUS:.*]] = cir.unary(minus, %[[TMP2]]) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> // CIR: cir.store{{.*}} %[[MINUS]], %[[MINUS_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> diff --git a/clang/test/CIR/IR/unary.cir b/clang/test/CIR/IR/unary.cir index d01d4eb3c920a..0fdf1dcfdfb47 100644 --- a/clang/test/CIR/IR/unary.cir +++ b/clang/test/CIR/IR/unary.cir @@ -9,42 +9,38 @@ module { cir.func @test_unary_unsigned() { %0 = cir.alloca !u32i, !cir.ptr<!u32i>, ["a"] {alignment = 4 : i64} %1 = cir.load %0 : !cir.ptr<!u32i>, !u32i - %2 = cir.unary(plus, %1) : !u32i, !u32i - %3 = cir.unary(minus, %1) : !u32i, !u32i - %4 = cir.unary(not, %1) : !u32i, !u32i - %5 = cir.unary(inc, %1) : !u32i, !u32i - %6 = cir.unary(dec, %1) : !u32i, !u32i + %2 = cir.unary(minus, %1) : !u32i, !u32i + %3 = cir.unary(not, %1) : !u32i, !u32i + %4 = cir.unary(inc, %1) : !u32i, !u32i + %5 = cir.unary(dec, %1) : !u32i, !u32i cir.return } // CHECK: cir.func{{.*}} @test_unary_unsigned() { // CHECK: %0 = cir.alloca !u32i, !cir.ptr<!u32i>, ["a"] {alignment = 4 : i64} // CHECK: %1 = cir.load %0 : !cir.ptr<!u32i>, !u32i -// CHECK: %2 = cir.unary(plus, %1) : !u32i, !u32i -// CHECK: %3 = cir.unary(minus, %1) : !u32i, !u32i -// CHECK: %4 = cir.unary(not, %1) : !u32i, !u32i -// CHECK: %5 = cir.unary(inc, %1) : !u32i, !u32i -// CHECK: %6 = cir.unary(dec, %1) : !u32i, !u32i +// CHECK: %2 = cir.unary(minus, %1) : !u32i, !u32i +// CHECK: %3 = cir.unary(not, %1) : !u32i, !u32i +// CHECK: %4 = cir.unary(inc, %1) : !u32i, !u32i +// CHECK: %5 = cir.unary(dec, %1) : !u32i, !u32i // CHECK: cir.return // CHECK: } cir.func @test_unary_signed() { %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["a"] {alignment = 4 : i64} %1 = cir.load %0 : !cir.ptr<!s32i>, !s32i - %2 = cir.unary(plus, %1) : !s32i, !s32i - %3 = cir.unary(minus, %1) nsw : !s32i, !s32i - %4 = cir.unary(not, %1) : !s32i, !s32i - %5 = cir.unary(inc, %1) nsw : !s32i, !s32i - %6 = cir.unary(dec, %1) nsw : !s32i, !s32i + %2 = cir.unary(minus, %1) nsw : !s32i, !s32i + %3 = cir.unary(not, %1) : !s32i, !s32i + %4 = cir.unary(inc, %1) nsw : !s32i, !s32i + %5 = cir.unary(dec, %1) nsw : !s32i, !s32i cir.return } // CHECK: cir.func{{.*}} @test_unary_signed() { // CHECK: %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["a"] {alignment = 4 : i64} // CHECK: %1 = cir.load %0 : !cir.ptr<!s32i>, !s32i -// CHECK: %2 = cir.unary(plus, %1) : !s32i, !s32i -// CHECK: %3 = cir.unary(minus, %1) nsw : !s32i, !s32i -// CHECK: %4 = cir.unary(not, %1) : !s32i, !s32i -// CHECK: %5 = cir.unary(inc, %1) nsw : !s32i, !s32i -// CHECK: %6 = cir.unary(dec, %1) nsw : !s32i, !s32i +// CHECK: %2 = cir.unary(minus, %1) nsw : !s32i, !s32i +// CHECK: %3 = cir.unary(not, %1) : !s32i, !s32i +// CHECK: %4 = cir.unary(inc, %1) nsw : !s32i, !s32i +// CHECK: %5 = cir.unary(dec, %1) nsw : !s32i, !s32i // CHECK: cir.return // CHECK: } } diff --git a/clang/test/CIR/Transforms/canonicalize.cir b/clang/test/CIR/Transforms/canonicalize.cir index cfac73ecdb738..7476126818082 100644 --- a/clang/test/CIR/Transforms/canonicalize.cir +++ b/clang/test/CIR/Transforms/canonicalize.cir @@ -117,78 +117,6 @@ module { // CHECK-NEXT: %[[CONST:.*]] = cir.const #cir.int<4294967294> : !u32i // CHECK-NEXT: cir.return %[[CONST]] : !u32i - cir.func @unary_plus_true() -> !cir.bool { - %0 = cir.const #true - %1 = cir.unary(plus, %0) : !cir.bool, !cir.bool - cir.return %1 : !cir.bool - } - // CHECK: cir.func{{.*}} @unary_plus_true() -> !cir.bool - // CHECK-NEXT: %[[CONST:.*]] = cir.const #true - // CHECK-NEXT: cir.return %[[CONST]] : !cir.bool - - cir.func @unary_plus_false() -> !cir.bool { - %0 = cir.const #false - %1 = cir.unary(plus, %0) : !cir.bool, !cir.bool - cir.return %1 : !cir.bool - } - // CHECK: cir.func{{.*}} @unary_plus_false() -> !cir.bool - // CHECK-NEXT: %[[CONST:.*]] = cir.const #false - // CHECK-NEXT: cir.return %[[CONST]] : !cir.bool - - cir.func @unary_plus_int() -> !s32i { - %0 = cir.const #cir.int<1> : !s32i - %1 = cir.unary(plus, %0) : !s32i, !s32i - cir.return %1 : !s32i - } - // CHECK: cir.func{{.*}} @unary_plus_int() -> !s32i - // CHECK-NEXT: %[[CONST:.*]] = cir.const #cir.int<1> : !s32i - // CHECK-NEXT: cir.return %[[CONST]] : !s32i - - cir.func @unary_plus_uint() -> !u32i { - %0 = cir.const #cir.int<1> : !u32i - %1 = cir.unary(plus, %0) : !u32i, !u32i - cir.return %1 : !u32i - } - // CHECK: cir.func{{.*}} @unary_plus_uint() -> !u32i - // CHECK-NEXT: %[[CONST:.*]] = cir.const #cir.int<1> : !u32i - // CHECK-NEXT: cir.return %[[CONST]] : !u32i - - cir.func @unary_plus_float() -> !cir.float { - %0 = cir.const #cir.fp<1.100000e+00> : !cir.float - %1 = cir.unary(plus, %0) : !cir.float, !cir.float - cir.return %1 : !cir.float - } - // CHECK: cir.func{{.*}} @unary_plus_float() -> !cir.float - // CHECK-NEXT: %[[CONST:.*]] = cir.const #cir.fp<1.100000e+00> : !cir.float - // CHECK-NEXT: cir.return %[[CONST]] : !cir.float - - cir.func @unary_plus_double() -> !cir.double { - %0 = cir.const #cir.fp<1.100000e+00> : !cir.double - %1 = cir.unary(plus, %0) : !cir.double, !cir.double - cir.return %1 : !cir.double - } - // CHECK: cir.func{{.*}} @unary_plus_double() -> !cir.double - // CHECK-NEXT: %[[CONST:.*]] = cir.const #cir.fp<1.100000e+00> : !cir.double - // CHECK-NEXT: cir.return %[[CONST]] : !cir.double - - cir.func @unary_plus_nan() -> !cir.float { - %0 = cir.const #cir.fp<0x7F800000> : !cir.float - %1 = cir.unary(plus, %0) : !cir.float, !cir.float - cir.return %1 : !cir.float - } - // CHECK: cir.func{{.*}} @unary_plus_nan() -> !cir.float - // CHECK-NEXT: %[[CONST:.*]] = cir.const #cir.fp<0x7F800000> : !cir.float - // CHECK-NEXT: cir.return %[[CONST]] : !cir.float - - cir.func @unary_plus_neg_nan() -> !cir.float { - %0 = cir.const #cir.fp<0xFF800000> : !cir.float - %1 = cir.unary(plus, %0) : !cir.float, !cir.float - cir.return %1 : !cir.float - } - // CHECK: cir.func{{.*}} @unary_plus_neg_nan() -> !cir.float - // CHECK-NEXT: %[[CONST:.*]] = cir.const #cir.fp<0xFF800000> : !cir.float - // CHECK-NEXT: cir.return %[[CONST]] : !cir.float - cir.func @unary_minus_true() -> !cir.bool { %0 = cir.const #true %1 = cir.unary(minus, %0) : !cir.bool, !cir.bool _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
