https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/226725
Split the Complex binary operations into float and int versions and remove the unnecessary range kind from div and mul int ops >From ff5ec3416adc35a3c7b088930819d877880a7bb3 Mon Sep 17 00:00:00 2001 From: Amr Hesham <[email protected]> Date: Sat, 26 Sep 2026 19:07:14 +0200 Subject: [PATCH] [CIR] Split ComplexBinOps for float and int --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 34 +++ clang/include/clang/CIR/Dialect/IR/CIROps.td | 106 +++++++-- .../CIR/Dialect/IR/CIRTypeConstraints.td | 13 ++ clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 12 +- .../Dialect/Transforms/LoweringPrepare.cpp | 212 +++++++++++------- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 174 ++++++++++---- .../CodeGen/complex-compound-assignment.cpp | 6 +- clang/test/CIR/CodeGen/complex-mul-div.cpp | 48 ++-- clang/test/CIR/CodeGen/complex-plus-minus.cpp | 12 +- clang/test/CIR/CodeGen/complex.cpp | 4 +- 10 files changed, 428 insertions(+), 193 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 36d583cfe9fbe..820e504a9c636 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -328,6 +328,40 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { return cir::ComplexImagOp::create(*this, loc, resultType, operand); } + mlir::Value createComplexAdd(mlir::Location loc, mlir::Value lhs, + mlir::Value rhs) { + auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType()); + if (cir::isAnyFloatingPointType(complexTy.getElementType())) + return cir::ComplexFAddOp::create(*this, loc, lhs, rhs); + return cir::ComplexAddOp::create(*this, loc, lhs, rhs); + } + + mlir::Value createComplexSub(mlir::Location loc, mlir::Value lhs, + mlir::Value rhs) { + auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType()); + if (cir::isAnyFloatingPointType(complexTy.getElementType())) + return cir::ComplexFSubOp::create(*this, loc, lhs, rhs); + return cir::ComplexSubOp::create(*this, loc, lhs, rhs); + } + + mlir::Value createComplexMul(mlir::Location loc, mlir::Value lhs, + mlir::Value rhs, + cir::ComplexRangeKind rangeKind) { + auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType()); + if (cir::isAnyFloatingPointType(complexTy.getElementType())) + return cir::ComplexFMulOp::create(*this, loc, lhs, rhs, rangeKind); + return cir::ComplexMulOp::create(*this, loc, lhs, rhs); + } + + mlir::Value createComplexDiv(mlir::Location loc, mlir::Value lhs, + mlir::Value rhs, + cir::ComplexRangeKind rangeKind) { + auto complexTy = mlir::cast<cir::ComplexType>(lhs.getType()); + if (cir::isAnyFloatingPointType(complexTy.getElementType())) + return cir::ComplexFDivOp::create(*this, loc, lhs, rhs, rangeKind); + return cir::ComplexDivOp::create(*this, loc, lhs, rhs); + } + mlir::Value createComplexConj(mlir::Location loc, mlir::Value operand) { return cir::ComplexConjOp::create(*this, loc, operand.getType(), operand); } diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 4996037ea5f56..6ad827cd66e89 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -6623,13 +6623,13 @@ def CIR_ComplexImagPtrOp : CIR_ComplexPartPtrOp<"complex.imag_ptr"> { } //===----------------------------------------------------------------------===// -// ComplexAddOp and ComplexSubOp +// Complex binary operations //===----------------------------------------------------------------------===// class CIR_ComplexBinOp<string mnemonic> : CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]> { - let arguments = (ins CIR_ComplexType:$lhs, CIR_ComplexType:$rhs); - let results = (outs CIR_ComplexType:$result); + let arguments = (ins CIR_ComplexOfIntType:$lhs, CIR_ComplexOfIntType:$rhs); + let results = (outs CIR_ComplexOfIntType:$result); let assemblyFormat = [{ $lhs `,` $rhs `:` qualified(type($result)) attr-dict @@ -6645,7 +6645,7 @@ def CIR_ComplexAddOp : CIR_ComplexBinOp<"complex.add"> { Example: ``` - %2 = cir.complex.add %0, %1 : !cir.complex<!cir.float> + %2 = cir.complex.add %0, %1 : !cir.complex<s32i> ``` }]; } @@ -6659,13 +6659,83 @@ def CIR_ComplexSubOp : CIR_ComplexBinOp<"complex.sub"> { Example: ``` - %2 = cir.complex.sub %0, %1 : !cir.complex<!cir.float> + %2 = cir.complex.sub %0, %1 : !cir.complex<s32i> + ``` + }]; +} + +def CIR_ComplexMulOp : CIR_ComplexBinOp<"complex.mul"> { + let summary = "Complex subtraction"; + let description = [{ + The `cir.complex.mul` operation takes two complex numbers and returns + their product. + + Example: + + ``` + %2 = cir.complex.mul %0, %1 : !cir.complex<s32i> + ``` + }]; + + let hasLLVMLowering = false; +} + +def CIR_ComplexDivOp : CIR_ComplexBinOp<"complex.div"> { + let summary = "Complex subtraction"; + let description = [{ + The `cir.complex.div` operation takes two complex numbers and returns + their quotient. + + Example: + + ``` + %2 = cir.complex.div %0, %1 : !cir.complex<s32i> + ``` + }]; + + let hasLLVMLowering = false; +} + +class CIR_ComplexFPBinOp<string mnemonic> + : CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]> { + let arguments = (ins CIR_ComplexOfFloatType:$lhs, CIR_ComplexOfFloatType:$rhs); + let results = (outs CIR_ComplexOfFloatType:$result); + + let assemblyFormat = [{ + $lhs `,` $rhs `:` qualified(type($result)) attr-dict + }]; +} + +def CIR_ComplexFAddOp : CIR_ComplexFPBinOp<"complex.fadd"> { + let summary = "Complex addition"; + let description = [{ + The `cir.complex.fadd` operation takes two complex numbers and returns + their sum. + + Example: + + ``` + %2 = cir.complex.fadd %0, %1 : !cir.complex<!cir.float> + ``` + }]; +} + +def CIR_ComplexFSubOp : CIR_ComplexFPBinOp<"complex.fsub"> { + let summary = "Complex subtraction"; + let description = [{ + The `cir.complex.fsub` operation takes two complex numbers and returns + their difference. + + Example: + + ``` + %2 = cir.complex.fsub %0, %1 : !cir.complex<!cir.float> ``` }]; } //===----------------------------------------------------------------------===// -// ComplexMulOp and ComplexDivOp +// Complex binary operations with range //===----------------------------------------------------------------------===// def CIR_ComplexRangeKind : CIR_I32Enum< @@ -6682,12 +6752,12 @@ def CIR_ComplexRangeKindAttr class CIR_ComplexRangeBinOp<string mnemonic> : CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]> { let arguments = (ins - CIR_ComplexType:$lhs, - CIR_ComplexType:$rhs, + CIR_ComplexOfFloatType:$lhs, + CIR_ComplexOfFloatType:$rhs, CIR_ComplexRangeKindAttr:$range ); - let results = (outs CIR_ComplexType:$result); + let results = (outs CIR_ComplexOfFloatType:$result); let assemblyFormat = [{ $lhs `,` $rhs `range` `(` enum($range) `)` `:` qualified(type($result)) @@ -6697,16 +6767,15 @@ class CIR_ComplexRangeBinOp<string mnemonic> let hasLLVMLowering = false; } -def CIR_ComplexMulOp : CIR_ComplexRangeBinOp<"complex.mul"> { +def CIR_ComplexFMulOp : CIR_ComplexRangeBinOp<"complex.fmul"> { let summary = "Complex multiplication"; let description = [{ The `cir.complex.mul` operation takes two complex numbers and returns their product. - For complex types with floating-point components, the `range` attribute - specifies the algorithm to be used when the operation is lowered to - the LLVM dialect. For multiplication, 'improved', 'promoted', and 'basic' - are all handled equivalently, producing the algebraic formula with no + The `range` attribute specifies the algorithm to be used when the operation + is lowered to the LLVM dialect. For multiplication, 'improved', 'promoted', + and 'basic' are all handled equivalently, producing the algebraic formula with no special handling for NaN value. If 'full' is used, a runtime-library function is called if one of the intermediate calculations produced a NaN value. @@ -6720,16 +6789,15 @@ def CIR_ComplexMulOp : CIR_ComplexRangeBinOp<"complex.mul"> { }]; } -def CIR_ComplexDivOp : CIR_ComplexRangeBinOp<"complex.div"> { +def CIR_ComplexFDivOp : CIR_ComplexRangeBinOp<"complex.fdiv"> { let summary = "Complex division"; let description = [{ The `cir.complex.div` operation takes two complex numbers and returns their quotient. - For complex types with floating-point components, the `range` attribute - specifies the algorithm to be used when the operation is lowered to - the LLVM dialect. For division, 'improved' produces Smith's algorithms for - Complex division with no additional handling for NaN values. If 'promoted' + The `range` attribute specifies the algorithm to be used when the operation + is lowered to the LLVM dialect. For division, 'improved' produces Smith's algorithms + for Complex division with no additional handling for NaN values. If 'promoted' is used, the values are promoted to a higher precision type, if possible, and the calculation is performed using the algebraic formula, with no additional handling for NaN values. We fall back on Smith's algorithm diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index c6afa74ba051f..a3de83f6cab63 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -202,6 +202,19 @@ def CIR_AnyIntOrBoolOrFloatType def CIR_AnyComplexType : CIR_TypeBase<"::cir::ComplexType", "complex type">; +class CIR_ComplexElementTypePred<Pred pred> : SubstLeaves<"$_self", + "::mlir::cast<::cir::ComplexType>($_self).getElementType()", pred>; + +class CIR_ComplexTypeOf<list<Type> types, string summary = ""> + : CIR_ConfinedType<CIR_AnyComplexType, + [Or<!foreach(type, types, CIR_ComplexElementTypePred<type.predicate>)>], + !if(!empty(summary), + "complex of " # CIR_TypeSummaries<types>.value, + summary)>; + +def CIR_ComplexOfIntType : CIR_ComplexTypeOf<[CIR_AnyIntType]>; +def CIR_ComplexOfFloatType : CIR_ComplexTypeOf<[CIR_AnyFloatType]>; + def CIR_AnyComplexOrIntOrBoolOrFloatType : AnyTypeOf<[CIR_AnyComplexType, CIR_AnyIntOrBoolOrFloatType], "complex, integer, boolean or floating point type"> { diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 91535c57132bd..7dd24a6d076e8 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -623,7 +623,7 @@ mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo &op) { if (mlir::isa<cir::ComplexType>(op.lhs.getType()) && mlir::isa<cir::ComplexType>(op.rhs.getType())) - return cir::ComplexAddOp::create(builder, op.loc, op.lhs, op.rhs); + return builder.createComplexAdd(op.loc, op.lhs, op.rhs); auto createAdd = [&](mlir::Location loc, mlir::Value a, mlir::Value b) { return cir::isFPOrVectorOfFPType(a.getType()) @@ -651,7 +651,7 @@ mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo &op) { if (mlir::isa<cir::ComplexType>(op.lhs.getType()) && mlir::isa<cir::ComplexType>(op.rhs.getType())) - return cir::ComplexSubOp::create(builder, op.loc, op.lhs, op.rhs); + return builder.createComplexSub(op.loc, op.lhs, op.rhs); auto createSub = [&](mlir::Location loc, mlir::Value a, mlir::Value b) { return cir::isFPOrVectorOfFPType(a.getType()) @@ -704,8 +704,7 @@ mlir::Value ComplexExprEmitter::emitBinMul(const BinOpInfo &op) { mlir::isa<cir::ComplexType>(op.rhs.getType())) { cir::ComplexRangeKind rangeKind = getComplexRangeAttr(op.fpFeatures.getComplexRange()); - return cir::ComplexMulOp::create(builder, op.loc, op.lhs, op.rhs, - rangeKind); + return builder.createComplexMul(op.loc, op.lhs, op.rhs, rangeKind); } auto createMul = [&](mlir::Location loc, mlir::Value a, mlir::Value b) { @@ -742,8 +741,7 @@ mlir::Value ComplexExprEmitter::emitBinDiv(const BinOpInfo &op) { mlir::isa<cir::ComplexType>(op.rhs.getType())) { cir::ComplexRangeKind rangeKind = getComplexRangeAttr(op.fpFeatures.getComplexRange()); - return cir::ComplexDivOp::create(builder, op.loc, op.lhs, op.rhs, - rangeKind); + return builder.createComplexDiv(op.loc, op.lhs, op.rhs, rangeKind); } // The C99 standard (G.5.1) defines division of a complex value by a real @@ -763,7 +761,7 @@ mlir::Value ComplexExprEmitter::emitBinDiv(const BinOpInfo &op) { mlir::Value lhs = builder.createComplexCreate(op.loc, op.lhs, nullValue); cir::ComplexRangeKind rangeKind = getComplexRangeAttr(op.fpFeatures.getComplexRange()); - return cir::ComplexDivOp::create(builder, op.loc, lhs, op.rhs, rangeKind); + return builder.createComplexDiv(op.loc, lhs, op.rhs, rangeKind); } mlir::Value CIRGenFunction::emitUnPromotedValue(mlir::Value result, diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index 9a3c9c9745eaa..7d30c71bb10ac 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -89,6 +89,8 @@ struct LoweringPreparePass void lowerComplexConjOp(cir::ComplexConjOp op); void lowerComplexDivOp(cir::ComplexDivOp op); void lowerComplexMulOp(cir::ComplexMulOp op); + void lowerComplexFDivOp(cir::ComplexFDivOp op); + void lowerComplexFMulOp(cir::ComplexFMulOp op); void lowerGetGlobalOp(cir::GetGlobalOp op); void lowerGlobalOp(cir::GlobalOp op); void lowerThreeWayCmpOp(cir::CmpThreeWayOp op); @@ -941,61 +943,81 @@ static mlir::Type higherPrecisionElementTypeForComplexArithmetic( return {}; } -static mlir::Value -lowerComplexDiv(LoweringPreparePass &pass, CIRBaseBuilderTy &builder, - mlir::Location loc, cir::ComplexDivOp op, mlir::Value lhsReal, - mlir::Value lhsImag, mlir::Value rhsReal, mlir::Value rhsImag, - mlir::MLIRContext &mlirCx, - const clang::TargetInfo &targetInfo) { +static mlir::Value lowerComplexFDiv(LoweringPreparePass &pass, + CIRBaseBuilderTy &builder, + mlir::Location loc, cir::ComplexFDivOp op, + mlir::Value lhsReal, mlir::Value lhsImag, + mlir::Value rhsReal, mlir::Value rhsImag, + mlir::MLIRContext &mlirCx, + const clang::TargetInfo &targetInfo) { cir::ComplexType complexTy = op.getType(); - if (mlir::isa<cir::FPTypeInterface>(complexTy.getElementType())) { - cir::ComplexRangeKind range = op.getRange(); - if (range == cir::ComplexRangeKind::Improved) + cir::ComplexRangeKind range = op.getRange(); + switch (range) { + case ComplexRangeKind::Full: { + return buildComplexBinOpLibCall(pass, builder, &getComplexDivLibCallName, + loc, complexTy, lhsReal, lhsImag, rhsReal, + rhsImag); + } + case ComplexRangeKind::Improved: { + return buildRangeReductionComplexDiv(builder, loc, lhsReal, lhsImag, + rhsReal, rhsImag); + } + case ComplexRangeKind::Promoted: { + mlir::Type originalElementType = complexTy.getElementType(); + mlir::Type higherPrecisionElementType = + higherPrecisionElementTypeForComplexArithmetic( + mlirCx, targetInfo, pass.getLangOpts(), builder, + originalElementType); + + if (!higherPrecisionElementType) return buildRangeReductionComplexDiv(builder, loc, lhsReal, lhsImag, rhsReal, rhsImag); - if (range == cir::ComplexRangeKind::Full) - return buildComplexBinOpLibCall(pass, builder, &getComplexDivLibCallName, - loc, complexTy, lhsReal, lhsImag, rhsReal, - rhsImag); - - if (range == cir::ComplexRangeKind::Promoted) { - mlir::Type originalElementType = complexTy.getElementType(); - mlir::Type higherPrecisionElementType = - higherPrecisionElementTypeForComplexArithmetic( - mlirCx, targetInfo, pass.getLangOpts(), builder, - originalElementType); - - if (!higherPrecisionElementType) - return buildRangeReductionComplexDiv(builder, loc, lhsReal, lhsImag, - rhsReal, rhsImag); - - cir::CastKind floatingCastKind = cir::CastKind::floating; - lhsReal = builder.createCast(floatingCastKind, lhsReal, - higherPrecisionElementType); - lhsImag = builder.createCast(floatingCastKind, lhsImag, - higherPrecisionElementType); - rhsReal = builder.createCast(floatingCastKind, rhsReal, - higherPrecisionElementType); - rhsImag = builder.createCast(floatingCastKind, rhsImag, - higherPrecisionElementType); - - mlir::Value algebraicResult = buildAlgebraicComplexDiv( - builder, loc, lhsReal, lhsImag, rhsReal, rhsImag); - - mlir::Value resultReal = builder.createComplexReal(loc, algebraicResult); - mlir::Value resultImag = builder.createComplexImag(loc, algebraicResult); - - mlir::Value finalReal = - builder.createCast(floatingCastKind, resultReal, originalElementType); - mlir::Value finalImag = - builder.createCast(floatingCastKind, resultImag, originalElementType); - return builder.createComplexCreate(loc, finalReal, finalImag); - } + cir::CastKind floatingCastKind = cir::CastKind::floating; + lhsReal = builder.createCast(floatingCastKind, lhsReal, + higherPrecisionElementType); + lhsImag = builder.createCast(floatingCastKind, lhsImag, + higherPrecisionElementType); + rhsReal = builder.createCast(floatingCastKind, rhsReal, + higherPrecisionElementType); + rhsImag = builder.createCast(floatingCastKind, rhsImag, + higherPrecisionElementType); + + mlir::Value algebraicResult = buildAlgebraicComplexDiv( + builder, loc, lhsReal, lhsImag, rhsReal, rhsImag); + + mlir::Value resultReal = builder.createComplexReal(loc, algebraicResult); + mlir::Value resultImag = builder.createComplexImag(loc, algebraicResult); + + mlir::Value finalReal = + builder.createCast(floatingCastKind, resultReal, originalElementType); + mlir::Value finalImag = + builder.createCast(floatingCastKind, resultImag, originalElementType); + return builder.createComplexCreate(loc, finalReal, finalImag); } + case ComplexRangeKind::Basic: { + return buildAlgebraicComplexDiv(builder, loc, lhsReal, lhsImag, rhsReal, + rhsImag); + } + } +} + +void LoweringPreparePass::lowerComplexFDivOp(cir::ComplexFDivOp op) { + cir::CIRBaseBuilderTy builder(getContext()); + builder.setInsertionPointAfter(op); + mlir::Location loc = op.getLoc(); + mlir::TypedValue<cir::ComplexType> lhs = op.getLhs(); + mlir::TypedValue<cir::ComplexType> rhs = op.getRhs(); + mlir::Value lhsReal = builder.createComplexReal(loc, lhs); + mlir::Value lhsImag = builder.createComplexImag(loc, lhs); + mlir::Value rhsReal = builder.createComplexReal(loc, rhs); + mlir::Value rhsImag = builder.createComplexImag(loc, rhs); - return buildAlgebraicComplexDiv(builder, loc, lhsReal, lhsImag, rhsReal, - rhsImag); + mlir::Value loweredResult = + lowerComplexFDiv(*this, builder, loc, op, lhsReal, lhsImag, rhsReal, + rhsImag, getContext(), getTargetInfo()); + op.replaceAllUsesWith(loweredResult); + op.erase(); } void LoweringPreparePass::lowerComplexDivOp(cir::ComplexDivOp op) { @@ -1009,9 +1031,8 @@ void LoweringPreparePass::lowerComplexDivOp(cir::ComplexDivOp op) { mlir::Value rhsReal = builder.createComplexReal(loc, rhs); mlir::Value rhsImag = builder.createComplexImag(loc, rhs); - mlir::Value loweredResult = - lowerComplexDiv(*this, builder, loc, op, lhsReal, lhsImag, rhsReal, - rhsImag, getContext(), getTargetInfo()); + mlir::Value loweredResult = buildAlgebraicComplexDiv( + builder, loc, lhsReal, lhsImag, rhsReal, rhsImag); op.replaceAllUsesWith(loweredResult); op.erase(); } @@ -1036,36 +1057,26 @@ getComplexMulLibCallName(llvm::APFloat::Semantics semantics) { } } -static mlir::Value lowerComplexMul(LoweringPreparePass &pass, - CIRBaseBuilderTy &builder, - mlir::Location loc, cir::ComplexMulOp op, - mlir::Value lhsReal, mlir::Value lhsImag, - mlir::Value rhsReal, mlir::Value rhsImag) { +static mlir::Value lowerComplexFMul(LoweringPreparePass &pass, + CIRBaseBuilderTy &builder, + mlir::Location loc, cir::ComplexFMulOp op, + mlir::Value lhsReal, mlir::Value lhsImag, + mlir::Value rhsReal, mlir::Value rhsImag) { // (a+bi) * (c+di) = (ac-bd) + (ad+bc)i - bool isFP = cir::isFPOrVectorOfFPType(lhsReal.getType()); - auto mul = [&](mlir::Location l, mlir::Value x, mlir::Value y) { - return isFP ? builder.createFMul(l, x, y) : builder.createMul(l, x, y); - }; - auto add = [&](mlir::Location l, mlir::Value x, mlir::Value y) { - return isFP ? builder.createFAdd(l, x, y) : builder.createAdd(l, x, y); - }; - auto sub = [&](mlir::Location l, mlir::Value x, mlir::Value y) { - return isFP ? builder.createFSub(l, x, y) : builder.createSub(l, x, y); - }; - - mlir::Value resultRealLhs = mul(loc, lhsReal, rhsReal); // ac - mlir::Value resultRealRhs = mul(loc, lhsImag, rhsImag); // bd - mlir::Value resultImagLhs = mul(loc, lhsReal, rhsImag); // ad - mlir::Value resultImagRhs = mul(loc, lhsImag, rhsReal); // bc - mlir::Value resultReal = sub(loc, resultRealLhs, resultRealRhs); - mlir::Value resultImag = add(loc, resultImagLhs, resultImagRhs); + mlir::Value resultRealLhs = builder.createFMul(loc, lhsReal, rhsReal); // ac + mlir::Value resultRealRhs = builder.createFMul(loc, lhsImag, rhsImag); // bd + mlir::Value resultImagLhs = builder.createFMul(loc, lhsReal, rhsImag); // ad + mlir::Value resultImagRhs = builder.createFMul(loc, lhsImag, rhsReal); // bc + mlir::Value resultReal = + builder.createFSub(loc, resultRealLhs, resultRealRhs); + mlir::Value resultImag = + builder.createFAdd(loc, resultImagLhs, resultImagRhs); mlir::Value algebraicResult = builder.createComplexCreate(loc, resultReal, resultImag); cir::ComplexType complexTy = op.getType(); cir::ComplexRangeKind rangeKind = op.getRange(); - if (mlir::isa<cir::IntType>(complexTy.getElementType()) || - rangeKind == cir::ComplexRangeKind::Basic || + if (rangeKind == cir::ComplexRangeKind::Basic || rangeKind == cir::ComplexRangeKind::Improved || rangeKind == cir::ComplexRangeKind::Promoted) return algebraicResult; @@ -1094,6 +1105,24 @@ static mlir::Value lowerComplexMul(LoweringPreparePass &pass, .getResult(); } +void LoweringPreparePass::lowerComplexFMulOp(cir::ComplexFMulOp op) { + cir::CIRBaseBuilderTy builder(getContext()); + builder.setInsertionPointAfter(op); + mlir::Location loc = op.getLoc(); + mlir::TypedValue<cir::ComplexType> lhs = op.getLhs(); + mlir::TypedValue<cir::ComplexType> rhs = op.getRhs(); + + // (a+bi) * (c+di) = (ac-bd) + (ad+bc)i + mlir::Value lhsReal = builder.createComplexReal(loc, lhs); + mlir::Value lhsImag = builder.createComplexImag(loc, lhs); + mlir::Value rhsReal = builder.createComplexReal(loc, rhs); + mlir::Value rhsImag = builder.createComplexImag(loc, rhs); + mlir::Value loweredResult = lowerComplexFMul(*this, builder, loc, op, lhsReal, + lhsImag, rhsReal, rhsImag); + op.replaceAllUsesWith(loweredResult); + op.erase(); +} + void LoweringPreparePass::lowerComplexMulOp(cir::ComplexMulOp op) { cir::CIRBaseBuilderTy builder(getContext()); builder.setInsertionPointAfter(op); @@ -1104,8 +1133,17 @@ void LoweringPreparePass::lowerComplexMulOp(cir::ComplexMulOp op) { mlir::Value lhsImag = builder.createComplexImag(loc, lhs); mlir::Value rhsReal = builder.createComplexReal(loc, rhs); mlir::Value rhsImag = builder.createComplexImag(loc, rhs); - mlir::Value loweredResult = lowerComplexMul(*this, builder, loc, op, lhsReal, - lhsImag, rhsReal, rhsImag); + + mlir::Value resultRealLhs = builder.createMul(loc, lhsReal, rhsReal); // ac + mlir::Value resultRealRhs = builder.createMul(loc, lhsImag, rhsImag); // bd + mlir::Value resultImagLhs = builder.createMul(loc, lhsReal, rhsImag); // ad + mlir::Value resultImagRhs = builder.createMul(loc, lhsImag, rhsReal); // bc + mlir::Value resultReal = builder.createSub(loc, resultRealLhs, resultRealRhs); + mlir::Value resultImag = builder.createAdd(loc, resultImagLhs, resultImagRhs); + + mlir::Value loweredResult = + builder.createComplexCreate(loc, resultReal, resultImag); + op.replaceAllUsesWith(loweredResult); op.erase(); } @@ -1154,9 +1192,9 @@ cir::FuncOp LoweringPreparePass::getOrCreateDtorFunc(CIRBaseBuilderTy &builder, // cir.call %_ZN1SD1Ev(%0) : (!cir.ptr<!rec_S>) -> () // (implicit cir.yield) // - // That is, if the second operation is a call that takes the get_global result - // as its only operand, and the only other operation is a yield, then we can - // just return the called function. + // That is, if the second operation is a call that takes the get_global + // result as its only operand, and the only other operation is a yield, then + // we can just return the called function. if (dtorBlock.getOperations().size() == 3) { auto callOp = mlir::dyn_cast<cir::CallOp>(&*(++opIt)); auto yieldOp = mlir::dyn_cast<cir::YieldOp>(&*(++opIt)); @@ -2459,6 +2497,10 @@ void LoweringPreparePass::runOnOp(mlir::Operation *op) { lowerCastOp(cast); } else if (auto complexConj = mlir::dyn_cast<cir::ComplexConjOp>(op)) { lowerComplexConjOp(complexConj); + } else if (auto complexDiv = mlir::dyn_cast<cir::ComplexFDivOp>(op)) { + lowerComplexFDivOp(complexDiv); + } else if (auto complexMul = mlir::dyn_cast<cir::ComplexFMulOp>(op)) { + lowerComplexFMulOp(complexMul); } else if (auto complexDiv = mlir::dyn_cast<cir::ComplexDivOp>(op)) { lowerComplexDivOp(complexDiv); } else if (auto complexMul = mlir::dyn_cast<cir::ComplexMulOp>(op)) { @@ -3084,10 +3126,10 @@ void LoweringPreparePass::runOnOperation() { mlirModule->walk([&](mlir::Operation *op) { if (mlir::isa<cir::ArrayCtor, cir::ArrayDtor, cir::CastOp, cir::ComplexConjOp, cir::ComplexMulOp, cir::ComplexDivOp, - cir::DynamicCastOp, cir::FuncOp, cir::CallOp, - cir::GetGlobalOp, cir::GlobalOp, cir::StoreOp, - cir::CmpThreeWayOp, cir::LocalInitOp, cir::StdOpInterface>( - op)) + cir::ComplexFMulOp, cir::ComplexFDivOp, cir::DynamicCastOp, + cir::FuncOp, cir::CallOp, cir::GetGlobalOp, cir::GlobalOp, + cir::StoreOp, cir::CmpThreeWayOp, cir::LocalInitOp, + cir::StdOpInterface>(op)) opsToTransform.push_back(op); }); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 4bdbe38df24e8..5a6a1a33ea333 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -5219,6 +5219,60 @@ mlir::LogicalResult CIRToLLVMVecTernaryOpLowering::matchAndRewrite( return mlir::success(); } +mlir::LogicalResult CIRToLLVMComplexCreateOpLowering::matchAndRewrite( + cir::ComplexCreateOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + mlir::Type complexLLVMTy = + getTypeConverter()->convertType(op.getResult().getType()); + auto initialComplex = + mlir::LLVM::UndefOp::create(rewriter, op->getLoc(), complexLLVMTy); + + auto realComplex = mlir::LLVM::InsertValueOp::create( + rewriter, op->getLoc(), initialComplex, adaptor.getReal(), + ArrayRef(int64_t{0})); + + auto complex = mlir::LLVM::InsertValueOp::create( + rewriter, op->getLoc(), realComplex, adaptor.getImag(), + ArrayRef(int64_t{1})); + + rewriter.replaceOp(op, complex); + return mlir::success(); +} + +mlir::LogicalResult CIRToLLVMComplexRealOpLowering::matchAndRewrite( + cir::ComplexRealOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + mlir::Type resultLLVMTy = getTypeConverter()->convertType(op.getType()); + mlir::Value operand = adaptor.getOperand(); + if (mlir::isa<cir::ComplexType>(op.getOperand().getType())) { + operand = mlir::LLVM::ExtractValueOp::create( + rewriter, op.getLoc(), resultLLVMTy, operand, + llvm::ArrayRef<std::int64_t>{0}); + } + rewriter.replaceOp(op, operand); + return mlir::success(); +} + +mlir::LogicalResult CIRToLLVMComplexImagOpLowering::matchAndRewrite( + cir::ComplexImagOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + mlir::Type resultLLVMTy = getTypeConverter()->convertType(op.getType()); + mlir::Value operand = adaptor.getOperand(); + mlir::Location loc = op.getLoc(); + + if (mlir::isa<cir::ComplexType>(op.getOperand().getType())) { + operand = mlir::LLVM::ExtractValueOp::create( + rewriter, loc, resultLLVMTy, operand, llvm::ArrayRef<std::int64_t>{1}); + } else { + mlir::TypedAttr zeroAttr = rewriter.getZeroAttr(resultLLVMTy); + operand = + mlir::LLVM::ConstantOp::create(rewriter, loc, resultLLVMTy, zeroAttr); + } + + rewriter.replaceOp(op, operand); + return mlir::success(); +} + mlir::LogicalResult CIRToLLVMComplexAddOpLowering::matchAndRewrite( cir::ComplexAddOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { @@ -5268,40 +5322,6 @@ mlir::LogicalResult CIRToLLVMComplexAddOpLowering::matchAndRewrite( return mlir::success(); } -mlir::LogicalResult CIRToLLVMComplexCreateOpLowering::matchAndRewrite( - cir::ComplexCreateOp op, OpAdaptor adaptor, - mlir::ConversionPatternRewriter &rewriter) const { - mlir::Type complexLLVMTy = - getTypeConverter()->convertType(op.getResult().getType()); - auto initialComplex = - mlir::LLVM::UndefOp::create(rewriter, op->getLoc(), complexLLVMTy); - - auto realComplex = mlir::LLVM::InsertValueOp::create( - rewriter, op->getLoc(), initialComplex, adaptor.getReal(), - ArrayRef(int64_t{0})); - - auto complex = mlir::LLVM::InsertValueOp::create( - rewriter, op->getLoc(), realComplex, adaptor.getImag(), - ArrayRef(int64_t{1})); - - rewriter.replaceOp(op, complex); - return mlir::success(); -} - -mlir::LogicalResult CIRToLLVMComplexRealOpLowering::matchAndRewrite( - cir::ComplexRealOp op, OpAdaptor adaptor, - mlir::ConversionPatternRewriter &rewriter) const { - mlir::Type resultLLVMTy = getTypeConverter()->convertType(op.getType()); - mlir::Value operand = adaptor.getOperand(); - if (mlir::isa<cir::ComplexType>(op.getOperand().getType())) { - operand = mlir::LLVM::ExtractValueOp::create( - rewriter, op.getLoc(), resultLLVMTy, operand, - llvm::ArrayRef<std::int64_t>{0}); - } - rewriter.replaceOp(op, operand); - return mlir::success(); -} - mlir::LogicalResult CIRToLLVMComplexSubOpLowering::matchAndRewrite( cir::ComplexSubOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { @@ -5351,23 +5371,83 @@ mlir::LogicalResult CIRToLLVMComplexSubOpLowering::matchAndRewrite( return mlir::success(); } -mlir::LogicalResult CIRToLLVMComplexImagOpLowering::matchAndRewrite( - cir::ComplexImagOp op, OpAdaptor adaptor, +mlir::LogicalResult CIRToLLVMComplexFAddOpLowering::matchAndRewrite( + cir::ComplexFAddOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { - mlir::Type resultLLVMTy = getTypeConverter()->convertType(op.getType()); - mlir::Value operand = adaptor.getOperand(); + mlir::Value lhs = adaptor.getLhs(); + mlir::Value rhs = adaptor.getRhs(); mlir::Location loc = op.getLoc(); - if (mlir::isa<cir::ComplexType>(op.getOperand().getType())) { - operand = mlir::LLVM::ExtractValueOp::create( - rewriter, loc, resultLLVMTy, operand, llvm::ArrayRef<std::int64_t>{1}); - } else { - mlir::TypedAttr zeroAttr = rewriter.getZeroAttr(resultLLVMTy); - operand = - mlir::LLVM::ConstantOp::create(rewriter, loc, resultLLVMTy, zeroAttr); - } + auto complexType = mlir::cast<cir::ComplexType>(op.getLhs().getType()); + mlir::Type complexElemTy = + getTypeConverter()->convertType(complexType.getElementType()); + auto lhsReal = mlir::LLVM::ExtractValueOp::create( + rewriter, loc, complexElemTy, lhs, ArrayRef(int64_t{0})); + auto lhsImag = mlir::LLVM::ExtractValueOp::create( + rewriter, loc, complexElemTy, lhs, ArrayRef(int64_t{1})); + auto rhsReal = mlir::LLVM::ExtractValueOp::create( + rewriter, loc, complexElemTy, rhs, ArrayRef(int64_t{0})); + auto rhsImag = mlir::LLVM::ExtractValueOp::create( + rewriter, loc, complexElemTy, rhs, ArrayRef(int64_t{1})); + + assert(!cir::MissingFeatures::fastMathFlags()); + assert(!cir::MissingFeatures::fpConstraints()); + mlir::Value newReal = mlir::LLVM::FAddOp::create(rewriter, loc, complexElemTy, + lhsReal, rhsReal); + mlir::Value newImag = mlir::LLVM::FAddOp::create(rewriter, loc, complexElemTy, + lhsImag, rhsImag); + + mlir::Type complexLLVMTy = + getTypeConverter()->convertType(op.getResult().getType()); + auto initialComplex = + mlir::LLVM::PoisonOp::create(rewriter, op->getLoc(), complexLLVMTy); + + auto realComplex = mlir::LLVM::InsertValueOp::create( + rewriter, op->getLoc(), initialComplex, newReal, ArrayRef(int64_t{0})); + + rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>( + op, realComplex, newImag, ArrayRef(int64_t{1})); + + return mlir::success(); +} + +mlir::LogicalResult CIRToLLVMComplexFSubOpLowering::matchAndRewrite( + cir::ComplexFSubOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + mlir::Value lhs = adaptor.getLhs(); + mlir::Value rhs = adaptor.getRhs(); + mlir::Location loc = op.getLoc(); + + auto complexType = mlir::cast<cir::ComplexType>(op.getLhs().getType()); + mlir::Type complexElemTy = + getTypeConverter()->convertType(complexType.getElementType()); + auto lhsReal = mlir::LLVM::ExtractValueOp::create( + rewriter, loc, complexElemTy, lhs, ArrayRef(int64_t{0})); + auto lhsImag = mlir::LLVM::ExtractValueOp::create( + rewriter, loc, complexElemTy, lhs, ArrayRef(int64_t{1})); + auto rhsReal = mlir::LLVM::ExtractValueOp::create( + rewriter, loc, complexElemTy, rhs, ArrayRef(int64_t{0})); + auto rhsImag = mlir::LLVM::ExtractValueOp::create( + rewriter, loc, complexElemTy, rhs, ArrayRef(int64_t{1})); + + assert(!cir::MissingFeatures::fastMathFlags()); + assert(!cir::MissingFeatures::fpConstraints()); + mlir::Value newReal = mlir::LLVM::FSubOp::create(rewriter, loc, complexElemTy, + lhsReal, rhsReal); + mlir::Value newImag = mlir::LLVM::FSubOp::create(rewriter, loc, complexElemTy, + lhsImag, rhsImag); + + mlir::Type complexLLVMTy = + getTypeConverter()->convertType(op.getResult().getType()); + auto initialComplex = + mlir::LLVM::PoisonOp::create(rewriter, op->getLoc(), complexLLVMTy); + + auto realComplex = mlir::LLVM::InsertValueOp::create( + rewriter, op->getLoc(), initialComplex, newReal, ArrayRef(int64_t{0})); + + rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>( + op, realComplex, newImag, ArrayRef(int64_t{1})); - rewriter.replaceOp(op, operand); return mlir::success(); } diff --git a/clang/test/CIR/CodeGen/complex-compound-assignment.cpp b/clang/test/CIR/CodeGen/complex-compound-assignment.cpp index e56717f064fa6..ba79157f38254 100644 --- a/clang/test/CIR/CodeGen/complex-compound-assignment.cpp +++ b/clang/test/CIR/CodeGen/complex-compound-assignment.cpp @@ -21,7 +21,7 @@ void foo() { // CIR: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> // CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> // CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR: %[[RESULT:.*]] = cir.complex.add %[[TMP_B]], %[[TMP_A]] : !cir.complex<!cir.float> +// CIR: %[[RESULT:.*]] = cir.complex.fadd %[[TMP_B]], %[[TMP_A]] : !cir.complex<!cir.float> // CIR: cir.store{{.*}} %[[RESULT]], %[[B_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>> // LLVM: %[[A_ADDR:.*]] = alloca { float, float }, align 4 @@ -65,7 +65,7 @@ void foo1() { // CIR: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> // CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> // CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR: %[[RESULT:.*]] = cir.complex.sub %[[TMP_B]], %[[TMP_A]] : !cir.complex<!cir.float> +// CIR: %[[RESULT:.*]] = cir.complex.fsub %[[TMP_B]], %[[TMP_A]] : !cir.complex<!cir.float> // CIR: cir.store{{.*}} %[[RESULT]], %[[B_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>> // LLVM: %[[A_ADDR:.*]] = alloca { float, float }, align 4 @@ -163,7 +163,7 @@ void foo3() { // CIR: %[[B_REAL_F32:.*]] = cir.cast floating %[[B_REAL]] : !cir.f16 -> !cir.float // CIR: %[[B_IMAG_F32:.*]] = cir.cast floating %[[B_IMAG]] : !cir.f16 -> !cir.float // CIR: %[[B_COMPLEX_F32:.*]] = cir.complex.create %[[B_REAL_F32]], %[[B_IMAG_F32]] : !cir.float -> !cir.complex<!cir.float> -// CIR: %[[ADD_A_B:.*]] = cir.complex.add %[[B_COMPLEX_F32]], %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> +// CIR: %[[ADD_A_B:.*]] = cir.complex.fadd %[[B_COMPLEX_F32]], %[[A_COMPLEX_F32]] : !cir.complex<!cir.float> // CIR: %[[ADD_REAL:.*]] = cir.complex.real %[[ADD_A_B]] : !cir.complex<!cir.float> -> !cir.float // CIR: %[[ADD_IMAG:.*]] = cir.complex.imag %[[ADD_A_B]] : !cir.complex<!cir.float> -> !cir.float // CIR: %[[ADD_REAL_F16:.*]] = cir.cast floating %[[ADD_REAL]] : !cir.float -> !cir.f16 diff --git a/clang/test/CIR/CodeGen/complex-mul-div.cpp b/clang/test/CIR/CodeGen/complex-mul-div.cpp index 13e3b39f7f10b..b357199ad2f10 100644 --- a/clang/test/CIR/CodeGen/complex-mul-div.cpp +++ b/clang/test/CIR/CodeGen/complex-mul-div.cpp @@ -40,11 +40,11 @@ void foo() { float _Complex c = a * b; } -// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} range(basic) : !cir.complex<!cir.float> +// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.fmul {{.*}}, {{.*}} range(basic) : !cir.complex<!cir.float> -// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} range(improved) : !cir.complex<!cir.float> +// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.fmul {{.*}}, {{.*}} range(improved) : !cir.complex<!cir.float> -// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} range(promoted) : !cir.complex<!cir.float> +// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.fmul {{.*}}, {{.*}} range(promoted) : !cir.complex<!cir.float> // CIR-AFTER-MUL-COMBINED: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> // CIR-AFTER-MUL-COMBINED: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> @@ -105,7 +105,7 @@ void foo() { // OGCG-MUL-COMBINED: store float %[[C_REAL]], ptr %[[C_REAL_PTR]], align 4 // OGCG-MUL-COMBINED: store float %[[C_IMAG]], ptr %[[C_IMAG_PTR]], align 4 -// CIR-BEFORE-FULL: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} range(full) : !cir.complex<!cir.float> +// CIR-BEFORE-FULL: %{{.*}} = cir.complex.fmul {{.*}}, {{.*}} range(full) : !cir.complex<!cir.float> // CIR-AFTER-FULL: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> // CIR-AFTER-FULL: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> @@ -217,13 +217,13 @@ void foo1() { int _Complex c = a * b; } -// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} range(basic) : !cir.complex<!s32i> +// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} : !cir.complex<!s32i> -// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} range(improved) : !cir.complex<!s32i> +// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} : !cir.complex<!s32i> -// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} range(promoted) : !cir.complex<!s32i> +// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} : !cir.complex<!s32i> -// CIR-BEFORE-FULL: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} range(full) : !cir.complex<!s32i> +// CIR-BEFORE-FULL: %{{.*}} = cir.complex.mul {{.*}}, {{.*}} : !cir.complex<!s32i> // CIR-AFTER-INT: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.complex<!s32i>> // CIR-AFTER-INT: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!s32i>> @@ -336,7 +336,7 @@ void foo3() { float _Complex c = a / b; } -// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(basic) : !cir.complex<!cir.float> +// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.fdiv {{.*}}, {{.*}} range(basic) : !cir.complex<!cir.float> // CIR-AFTER-BASIC: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> // CIR-AFTER-BASIC: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> @@ -412,7 +412,7 @@ void foo3() { // OGCG-BASIC: store float %[[RESULT_REAL]], ptr %[[C_REAL_PTR]], align 4 // OGCG-BASIC: store float %[[RESULT_IMAG]], ptr %[[C_IMAG_PTR]], align 4 -// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(improved) : !cir.complex<!cir.float> +// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.fdiv {{.*}}, {{.*}} range(improved) : !cir.complex<!cir.float> // CIR-AFTER-IMPROVED: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> // CIR-AFTER-IMPROVED: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> @@ -543,7 +543,7 @@ void foo3() { // OGCG-IMPROVED: store float %[[RESULT_REAL]], ptr %[[C_REAL_PTR]], align 4 // OGCG-IMPROVED: store float %[[RESULT_IMAG]], ptr %[[C_IMAG_PTR]], align 4 -// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(promoted) : !cir.complex<!cir.float> +// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.fdiv {{.*}}, {{.*}} range(promoted) : !cir.complex<!cir.float> // CIR-AFTER-PROMOTED: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> // CIR-AFTER-PROMOTED: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> @@ -642,7 +642,7 @@ void foo3() { // OGCG-PROMOTED: store float %[[UNPROMOTION_RESULT_REAL]], ptr %[[C_REAL_PTR]], align 4 // OGCG-PROMOTED: store float %[[UNPROMOTION_RESULT_IMAG]], ptr %[[C_IMAG_PTR]], align 4 -// CIR-BEFORE-FULL: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(full) : !cir.complex<!cir.float> +// CIR-BEFORE-FULL: %{{.*}} = cir.complex.fdiv {{.*}}, {{.*}} range(full) : !cir.complex<!cir.float> // CIR-AFTER-FULL: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> // CIR-AFTER-FULL: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> @@ -702,13 +702,13 @@ void foo4() { int _Complex c = a / b; } -// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(basic) : !cir.complex<!s32i> +// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.div {{.*}}, {{.*}} : !cir.complex<!s32i> -// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(improved) : !cir.complex<!s32i> +// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} : !cir.complex<!s32i> -// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(promoted) : !cir.complex<!s32i> +// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} : !cir.complex<!s32i> -// CIR-BEFORE-FULL: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(full) : !cir.complex<!s32i> +// CIR-BEFORE-FULL: %{{.*}} = cir.complex.div {{.*}}, {{.*}} : !cir.complex<!s32i> // CIR-COMBINED: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.complex<!s32i>> // CIR-COMBINED: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!s32i>> @@ -836,7 +836,7 @@ void foo6() { float _Complex c = a / b; } -// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(basic) : !cir.complex<!cir.float> +// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.fdiv {{.*}}, {{.*}} range(basic) : !cir.complex<!cir.float> // CIR-AFTER-BASIC: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.float> // CIR-AFTER-BASIC: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> @@ -911,7 +911,7 @@ void foo6() { // OGCG-BASIC: store float %[[RESULT_REAL]], ptr %[[C_REAL_PTR]], align 4 // OGCG-BASIC: store float %[[RESULT_IMAG]], ptr %[[C_IMAG_PTR]], align 4 -// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(improved) : !cir.complex<!cir.float> +// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.fdiv {{.*}}, {{.*}} range(improved) : !cir.complex<!cir.float> // CIR-AFTER-IMPROVED: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.float> // CIR-AFTER-IMPROVED: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> @@ -1041,7 +1041,7 @@ void foo6() { // OGCG-IMPROVED: store float %[[RESULT_REAL]], ptr %[[C_REAL_PTR]], align 4 // OGCG-IMPROVED: store float %[[RESULT_IMAG]], ptr %[[C_IMAG_PTR]], align 4 -// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(promoted) : !cir.complex<!cir.float> +// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.fdiv {{.*}}, {{.*}} range(promoted) : !cir.complex<!cir.float> // CIR-AFTER-PROMOTED: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.float> // CIR-AFTER-PROMOTED: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> @@ -1137,7 +1137,7 @@ void foo6() { // OGCG-PROMOTED: store float %[[UNPROMOTION_RESULT_REAL]], ptr %[[C_REAL_PTR]], align 4 // OGCG-PROMOTED: store float %[[UNPROMOTION_RESULT_IMAG]], ptr %[[C_IMAG_PTR]], align 4 -// CIR-BEFORE-FULL: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(full) : !cir.complex<!cir.float> +// CIR-BEFORE-FULL: %{{.*}} = cir.complex.fdiv {{.*}}, {{.*}} range(full) : !cir.complex<!cir.float> // CIR-AFTER-FULL: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.float> // CIR-AFTER-FULL: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> @@ -1196,13 +1196,13 @@ void foo7() { int _Complex c = a / b; } -// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(basic) : !cir.complex<!s32i> +// CIR-BEFORE-BASIC: %{{.*}} = cir.complex.div {{.*}}, {{.*}} : !cir.complex<!s32i> -// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(improved) : !cir.complex<!s32i> +// CIR-BEFORE-IMPROVED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} : !cir.complex<!s32i> -// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(promoted) : !cir.complex<!s32i> +// CIR-BEFORE-PROMOTED: %{{.*}} = cir.complex.div {{.*}}, {{.*}} : !cir.complex<!s32i> -// CIR-BEFORE-FULL: %{{.*}} = cir.complex.div {{.*}}, {{.*}} range(full) : !cir.complex<!s32i> +// CIR-BEFORE-FULL: %{{.*}} = cir.complex.div {{.*}}, {{.*}} : !cir.complex<!s32i> // CIR-COMBINED: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!cir.complex<!s32i>> // CIR-COMBINED: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!s32i> diff --git a/clang/test/CIR/CodeGen/complex-plus-minus.cpp b/clang/test/CIR/CodeGen/complex-plus-minus.cpp index 31c16310786fe..b0949364f6e0e 100644 --- a/clang/test/CIR/CodeGen/complex-plus-minus.cpp +++ b/clang/test/CIR/CodeGen/complex-plus-minus.cpp @@ -58,7 +58,7 @@ void foo2() { // CIR: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> // CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> // CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR: %[[ADD:.*]] = cir.complex.add %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float> +// CIR: %[[ADD:.*]] = cir.complex.fadd %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float> // LLVM: %[[A_ADDR:.*]] = alloca { float, float }, align 4 // LLVM: %[[B_ADDR:.*]] = alloca { float, float }, align 4 @@ -104,9 +104,9 @@ void foo3() { // CIR: %[[RESULT:.*]] = cir.alloca "d" {{.*}} init : !cir.ptr<!cir.complex<!cir.float>> // CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> // CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR: %[[ADD_A_B:.*]] = cir.complex.add %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float> +// CIR: %[[ADD_A_B:.*]] = cir.complex.fadd %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float> // CIR: %[[TMP_C:.*]] = cir.load{{.*}} %[[C_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR: %[[ADD_A_B_C:.*]] = cir.complex.add %[[ADD_A_B]], %[[TMP_C]] : !cir.complex<!cir.float> +// CIR: %[[ADD_A_B_C:.*]] = cir.complex.fadd %[[ADD_A_B]], %[[TMP_C]] : !cir.complex<!cir.float> // CIR: cir.store{{.*}} %[[ADD_A_B_C]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>> // LLVM: %[[A_ADDR:.*]] = alloca { float, float }, align 4 @@ -214,7 +214,7 @@ void foo5() { // CIR: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!cir.complex<!cir.float>> // CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> // CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR: %[[SUB:.*]] = cir.complex.sub %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float> +// CIR: %[[SUB:.*]] = cir.complex.fsub %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float> // LLVM: %[[A_ADDR:.*]] = alloca { float, float }, align 4 // LLVM: %[[B_ADDR:.*]] = alloca { float, float }, align 4 @@ -260,9 +260,9 @@ void foo6() { // CIR: %[[RESULT:.*]] = cir.alloca "d" {{.*}} init : !cir.ptr<!cir.complex<!cir.float>> // CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> // CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR: %[[SUB_A_B:.*]] = cir.complex.sub %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float> +// CIR: %[[SUB_A_B:.*]] = cir.complex.fsub %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float> // CIR: %[[TMP_C:.*]] = cir.load{{.*}} %[[C_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float> -// CIR: %[[SUB_A_B_C:.*]] = cir.complex.sub %[[SUB_A_B]], %[[TMP_C]] : !cir.complex<!cir.float> +// CIR: %[[SUB_A_B_C:.*]] = cir.complex.fsub %[[SUB_A_B]], %[[TMP_C]] : !cir.complex<!cir.float> // CIR: cir.store{{.*}} %[[SUB_A_B_C]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>> // LLVM: %[[A_ADDR:.*]] = alloca { float, float }, align 4 diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index 99b30cae657b5..1a3c7e6b6d3af 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -1984,10 +1984,10 @@ void compare_two_complex_bin_ops() { // CIR: %[[C_ADDR:.*]] = cir.alloca "c" {{.*}} init : !cir.ptr<!cir.bool> // CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double> // CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double> -// CIR: %[[COMPLEX_AB:.*]] = cir.complex.add %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.double> +// CIR: %[[COMPLEX_AB:.*]] = cir.complex.fadd %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.double> // CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double> // CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double> -// CIR: %[[COMPLEX_BA:.*]] = cir.complex.add %[[TMP_B]], %[[TMP_A]] : !cir.complex<!cir.double> +// CIR: %[[COMPLEX_BA:.*]] = cir.complex.fadd %[[TMP_B]], %[[TMP_A]] : !cir.complex<!cir.double> // CIR: %[[RESULT:.*]] = cir.cmp ne %[[COMPLEX_AB]], %[[COMPLEX_BA]] : !cir.complex<!cir.double> // CIR: cir.store {{.*}} %[[RESULT]], %[[C_ADDR]] : !cir.bool, !cir.ptr<!cir.bool> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
