https://github.com/zahiraam created https://github.com/llvm/llvm-project/pull/81316
division. >From 5cf9dd1073ce6ae72aebbbd8fc4723ec48b39816 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Fri, 9 Feb 2024 12:38:34 -0800 Subject: [PATCH] Full control of range reduction for complex multiplication and division. --- clang/include/clang/Basic/LangOptions.h | 26 ++- clang/include/clang/Driver/Options.td | 10 +- clang/lib/CodeGen/CGExprComplex.cpp | 28 ++- clang/lib/Driver/ToolChains/Clang.cpp | 86 +++---- clang/test/CodeGen/cx-complex-range.c | 232 +++++++++++-------- clang/test/CodeGen/pragma-cx-limited-range.c | 2 +- clang/test/Driver/range.c | 101 +++++--- 7 files changed, 307 insertions(+), 178 deletions(-) diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index c1cc5548ef10c0..5ef29909bfa502 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -414,7 +414,31 @@ class LangOptions : public LangOptionsBase { IncompleteOnly = 3, }; - enum ComplexRangeKind { CX_Full, CX_Limited, CX_Fortran, CX_None }; + /// Controls for the complex arithmetic range rules. + enum ComplexRangeKind { + /// Implementation of complex division and multiplication using a call to + /// runtime library functions (generally the case, but the BE might + /// sometimes replace the library call if it knows enough about the + /// potential range of the inputs). Overflow and non-finite values are + /// handled. + CX_Full, + + /// Implementation of complex division using the Smith algorithm at source + /// precision. Overflow is handled. + CX_Smith, + + /// Implementation of complex division using algebraic formulas at higher + /// precision. Overflow is handled. + CX_Extend, + + /// Implementation of complex division and multiplication using algebraic + /// formulas at source precision. Overflow and non-finites values are not + /// handled. + CX_Limited, + + /// No range rule is enabled. + CX_None + }; public: /// The used language standard. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 4b232b8aab722a..527ab27a3d2358 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1030,12 +1030,18 @@ def fno_cx_fortran_rules : Joined<["-"], "fno-cx-fortran-rules">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>, HelpText<"Range reduction is disabled for complex arithmetic operations.">; +def fcomplex_arithmetic_EQ : Joined<["-"], "fcomplex-arithmetic=">, Group<f_Group>, + Visibility<[ClangOption, CC1Option]>, + Values<"full,smith,extend,limited">, NormalizedValuesScope<"LangOptions">, + NormalizedValues<["CX_Full", "CX_Smith", "CX_Extend", "CX_Limited"]>; + def complex_range_EQ : Joined<["-"], "complex-range=">, Group<f_Group>, Visibility<[CC1Option]>, - Values<"full,limited,fortran">, NormalizedValuesScope<"LangOptions">, - NormalizedValues<["CX_Full", "CX_Limited", "CX_Fortran"]>, + Values<"full,smith,extend,limited">, NormalizedValuesScope<"LangOptions">, + NormalizedValues<["CX_Full", "CX_Smith", "CX_Extend", "CX_Limited"]>, MarshallingInfoEnum<LangOpts<"ComplexRange">, "CX_Full">; + // OpenCL-only Options def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 9ddf0e763f139b..f41c69190b0e5c 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -283,9 +283,23 @@ class ComplexExprEmitter ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName, const BinOpInfo &Op); - QualType getPromotionType(QualType Ty) { + QualType getPromotionType(QualType Ty, bool IsDivOpCode = false) { if (auto *CT = Ty->getAs<ComplexType>()) { QualType ElementType = CT->getElementType(); + if (CGF.getLangOpts().getComplexRange() == + LangOptions::ComplexRangeKind::CX_Extend && + IsDivOpCode) { + if (ElementType->isFloatingType()) { + if (const auto *BT = dyn_cast<BuiltinType>(ElementType)) + switch (BT->getKind()) { + case BuiltinType::Kind::Float: + return CGF.getContext().getComplexType(CGF.getContext().DoubleTy); + default: + return CGF.getContext().getComplexType( + CGF.getContext().LongDoubleTy); + } + } + } if (ElementType.UseExcessPrecision(CGF.getContext())) return CGF.getContext().getComplexType(CGF.getContext().FloatTy); } @@ -296,7 +310,9 @@ class ComplexExprEmitter #define HANDLEBINOP(OP) \ ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \ - QualType promotionTy = getPromotionType(E->getType()); \ + QualType promotionTy = getPromotionType( \ + E->getType(), \ + (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false); \ ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \ if (!promotionTy.isNull()) \ result = \ @@ -790,7 +806,8 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { ResI = Builder.CreateFAdd(AD, BC, "mul_i"); if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Limited || - Op.FPFeatures.getComplexRange() == LangOptions::CX_Fortran) + Op.FPFeatures.getComplexRange() == LangOptions::CX_Smith || + Op.FPFeatures.getComplexRange() == LangOptions::CX_Extend) return ComplexPairTy(ResR, ResI); // Emit the test for the real part becoming NaN and create a branch to @@ -981,9 +998,10 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { llvm::Value *OrigLHSi = LHSi; if (!LHSi) LHSi = llvm::Constant::getNullValue(RHSi->getType()); - if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Fortran) + if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Smith) return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi); - else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Limited) + else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Limited || + Op.FPFeatures.getComplexRange() == LangOptions::CX_Extend) return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi); else if (!CGF.getLangOpts().FastMath || // '-ffast-math' is used in the command line but followed by an diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 13bf2421154372..f990249fb059cd 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2688,17 +2688,17 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } static StringRef EnumComplexRangeToStr(LangOptions::ComplexRangeKind Range) { - StringRef RangeStr = ""; switch (Range) { case LangOptions::ComplexRangeKind::CX_Limited: - return "-fcx-limited-range"; - break; - case LangOptions::ComplexRangeKind::CX_Fortran: - return "-fcx-fortran-rules"; - break; + return "-fcomplex-arithmetic=limited"; + case LangOptions::ComplexRangeKind::CX_Smith: + return "-fcomplex-arithmetic=smith"; + case LangOptions::ComplexRangeKind::CX_Extend: + return "-fcomplex-arithmetic=extend"; + case LangOptions::ComplexRangeKind::CX_Full: + return "-fcomplex-arithmetic=full"; default: - return RangeStr; - break; + return ""; } } @@ -2710,22 +2710,30 @@ static void EmitComplexRangeDiag(const Driver &D, << EnumComplexRangeToStr(Range1) << EnumComplexRangeToStr(Range2); } -static std::string -RenderComplexRangeOption(LangOptions::ComplexRangeKind Range) { - std::string ComplexRangeStr = "-complex-range="; +static std::string ComplexRangeToStr(LangOptions::ComplexRangeKind Range) { switch (Range) { case LangOptions::ComplexRangeKind::CX_Full: - ComplexRangeStr += "full"; + return "full"; break; case LangOptions::ComplexRangeKind::CX_Limited: - ComplexRangeStr += "limited"; + return "limited"; break; - case LangOptions::ComplexRangeKind::CX_Fortran: - ComplexRangeStr += "fortran"; + case LangOptions::ComplexRangeKind::CX_Smith: + return "smith"; + break; + case LangOptions::ComplexRangeKind::CX_Extend: + return "extend"; break; default: - assert(0 && "Unexpected range option"); + return ""; } +} + +static std::string +RenderComplexRangeOption(LangOptions::ComplexRangeKind Range) { + std::string ComplexRangeStr = ComplexRangeToStr(Range); + if (!ComplexRangeStr.empty()) + return "-complex-range=" + ComplexRangeStr; return ComplexRangeStr; } @@ -2789,24 +2797,24 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, switch (optID) { default: break; - case options::OPT_fcx_limited_range: { - EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Limited); - Range = LangOptions::ComplexRangeKind::CX_Limited; - break; - } - case options::OPT_fno_cx_limited_range: - EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full); - Range = LangOptions::ComplexRangeKind::CX_Full; - break; - case options::OPT_fcx_fortran_rules: { - EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Fortran); - Range = LangOptions::ComplexRangeKind::CX_Fortran; + case options::OPT_fcomplex_arithmetic_EQ: { + LangOptions::ComplexRangeKind RangeVal; + StringRef Val = A->getValue(); + if (Val.equals("full")) + RangeVal = LangOptions::ComplexRangeKind::CX_Full; + else if (Val.equals("smith")) + RangeVal = LangOptions::ComplexRangeKind::CX_Smith; + else if (Val.equals("extend")) + RangeVal = LangOptions::ComplexRangeKind::CX_Extend; + else if (Val.equals("limited")) + RangeVal = LangOptions::ComplexRangeKind::CX_Limited; + else + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getSpelling() << LangOptions::ComplexRangeKind::CX_None; + EmitComplexRangeDiag(D, Range, RangeVal); + Range = RangeVal; break; } - case options::OPT_fno_cx_fortran_rules: - EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full); - Range = LangOptions::ComplexRangeKind::CX_Full; - break; case options::OPT_ffp_model_EQ: { // If -ffp-model= is seen, reset to fno-fast-math HonorINFs = true; @@ -3235,16 +3243,12 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, if (Range != LangOptions::ComplexRangeKind::CX_None) ComplexRangeStr = RenderComplexRangeOption(Range); - if (!ComplexRangeStr.empty()) + if (!ComplexRangeStr.empty()) { CmdArgs.push_back(Args.MakeArgString(ComplexRangeStr)); - if (Args.hasArg(options::OPT_fcx_limited_range)) - CmdArgs.push_back("-fcx-limited-range"); - if (Args.hasArg(options::OPT_fcx_fortran_rules)) - CmdArgs.push_back("-fcx-fortran-rules"); - if (Args.hasArg(options::OPT_fno_cx_limited_range)) - CmdArgs.push_back("-fno-cx-limited-range"); - if (Args.hasArg(options::OPT_fno_cx_fortran_rules)) - CmdArgs.push_back("-fno-cx-fortran-rules"); + if (Args.hasArg(options::OPT_fcomplex_arithmetic_EQ)) + CmdArgs.push_back(Args.MakeArgString("-fcomplex-arithmetic=" + + ComplexRangeToStr(Range))); + } } static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs, diff --git a/clang/test/CodeGen/cx-complex-range.c b/clang/test/CodeGen/cx-complex-range.c index 2d8507c710f202..02c5fc57547ce9 100644 --- a/clang/test/CodeGen/cx-complex-range.c +++ b/clang/test/CodeGen/cx-complex-range.c @@ -5,120 +5,156 @@ // RUN: -complex-range=limited -o - | FileCheck %s --check-prefix=LMTD // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fno-cx-limited-range -o - | FileCheck %s --check-prefix=FULL +// RUN: -complex-range=smith -o - | FileCheck %s --check-prefix=FRTRN // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -complex-range=fortran -o - | FileCheck %s --check-prefix=FRTRN +// RUN: -complex-range=extend -o - | FileCheck %s --check-prefix=EXTND + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -complex-range=full -o - | FileCheck %s --check-prefix=FULL // Fast math // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ // RUN: -ffast-math -complex-range=limited -emit-llvm -o - %s \ -// RUN: | FileCheck %s --check-prefix=LMTD-FAST +// RUN: | FileCheck %s --check-prefix=LMTD // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ // RUN: -ffast-math -complex-range=full -emit-llvm -o - %s \ // RUN: | FileCheck %s --check-prefix=FULL -// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fno-cx-fortran-rules -o - | FileCheck %s --check-prefix=FULL - -// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fcx-limited-range -fno-cx-limited-range -o - \ -// RUN: | FileCheck %s --check-prefix=FULL - -// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fno-cx-limited-range -fcx-limited-range -o - \ -// RUN: | FileCheck %s --check-prefix=FULL - -// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fno-cx-fortran-rules -fcx-fortran-rules -o - \ -// RUN: | FileCheck %s --check-prefix=FULL +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ +// RUN: -ffast-math -complex-range=smith -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=FRTRN +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ +// RUN: -ffast-math -complex-range=extend -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=EXTND + +// LABEL: define {{.*}} @div( +// FULL: call {{.*}} @__divsc3 +// +// LMTD: fmul{{.*}}float +// LMTD-NEXT: fmul{{.*}}float +// LMTD-NEXT: fadd{{.*}}float +// LMTD-NEXT: fmul{{.*}}float +// LMTD-NEXT: fmul{{.*}}float +// LMTD-NEXT: fadd{{.*}}float +// LMTD-NEXT: fmul{{.*}}float +// LMTD-NEXT: fmul{{.*}}float +// LMTD-NEXT: fsub{{.*}}float +// LMTD-NEXT: fdiv{{.*}}float +// LMTD-NEXT: fdiv{{.*}}float +// +// FRTRN: call{{.*}}float @llvm.fabs.f32(float {{.*}}) +// FRTRN-NEXT: call{{.*}}float @llvm.fabs.f32(float {{.*}}) +// FRTRN-NEXT: fcmp{{.*}}ugt float {{.*}}, {{.*}} +// FRTRN-NEXT: br i1 {{.*}}, label +// FRTRN: abs_rhsr_greater_or_equal_abs_rhsi: +// FRTRN-NEXT: fdiv{{.*}}float +// FRTRN-NEXT: fmul{{.*}}float +// FRTRN-NEXT: fadd{{.*}}float +// FRTRN-NEXT: fmul{{.*}}float +// FRTRN-NEXT: fadd{{.*}}float +// FRTRN-NEXT: fdiv{{.*}}float +// FRTRN-NEXT: fmul{{.*}}float +// FRTRN-NEXT: fsub{{.*}}float +// FRTRN-NEXT: fdiv{{.*}}float +// FRTRN-NEXT: br label +// FRTRN: abs_rhsr_less_than_abs_rhsi: +// FRTRN-NEXT: fdiv{{.*}}float +// FRTRN-NEXT: fmul{{.*}}float +// FRTRN-NEXT: fadd{{.*}}float +// FRTRN-NEXT: fmul{{.*}}float +// FRTRN-NEXT: fadd{{.*}}float +// FRTRN-NEXT: fdiv{{.*}}float +// FRTRN-NEXT: fmul{{.*}}float +// FRTRN-NEXT: fsub{{.*}}float +// FRTRN-NEXT: fdiv{{.*}}float +// +// EXTND: load float, ptr {{.*}} +// EXTND: fpext float {{.*}} to double +// EXTND-NEXT: fpext float {{.*}} to double +// EXTND-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 0 +// EXTND-NEXT: load float, ptr {{.*}} +// EXTND-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 1 +// EXTND-NEXT: load float, ptr {{.*}} +// EXTND-NEXT: fpext float {{.*}} to double +// EXTND-NEXT: fpext float {{.*}} to double +// EXTND-NEXT: fmul{{.*}}double +// EXTND-NEXT: fmul{{.*}}double +// EXTND-NEXT: fadd{{.*}}double +// EXTND-NEXT: fmul{{.*}}double +// EXTND-NEXT: fmul{{.*}}double +// EXTND-NEXT: fadd{{.*}}double +// EXTND-NEXT: fmul{{.*}}double +// EXTND-NEXT: fmul{{.*}}double +// EXTND-NEXT: fsub{{.*}}double +// EXTND-NEXT: fdiv{{.*}}double +// EXTND-NEXT: fdiv{{.*}}double +// EXTND-NEXT: fptrunc double {{.*}} to float +// EXTND-NEXT: fptrunc double {{.*}} to float +// _Complex float div(_Complex float a, _Complex float b) { - // LABEL: define {{.*}} @div( - // FULL: call {{.*}} @__divsc3 - - // LMTD: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fadd float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fadd float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fsub float - // LMTD-NEXT: fdiv float - // LMTD-NEXT: fdiv float - - // FRTRN: call {{.*}}float @llvm.fabs.f32(float {{.*}}) - // FRTRN-NEXT: call {{.*}}float @llvm.fabs.f32(float {{.*}}) - // FRTRN-NEXT: fcmp {{.*}}ugt float - // FRTRN-NEXT: br i1 {{.*}}, label - // FRTRN: abs_rhsr_greater_or_equal_abs_rhsi: - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fadd {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fadd {{.*}}float - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fsub {{.*}}float - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: br label - // FRTRN: abs_rhsr_less_than_abs_rhsi: - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fadd {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fadd {{.*}}float - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fsub {{.*}}float - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: br label - // FRTRN: complex_div: - // FRTRN-NEXT: phi {{.*}}float - // FRTRN-NEXT: phi {{.*}}float - - // LMTD-FAST: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fadd {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fadd {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fsub {{.*}} float - // LMTD-FAST-NEXT: fdiv {{.*}} float - // LMTD-FAST-NEXT: fdiv {{.*}} float - return a / b; } +// LABEL: define {{.*}} @mul( +// FULL: call {{.*}} @__mulsc3 +// +// LMTD: alloca { float, float } +// LMTD-NEXT: alloca { float, float } +// LMTD-NEXT: alloca { float, float } +// LMTD: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 0 +// LMTD-NEXT: load float, ptr {{.*}} +// LMTD-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 1 +// LMTD-NEXT: load float, ptr {{.*}} +// LMTD-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 0 +// LMTD-NEXT: load float, ptr {{.*}} +// LMTD-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 1 +// LMTD-NEXT: load float +// LMTD-NEXT: fmul{{.*}}float +// LMTD-NEXT: fmul{{.*}}float +// LMTD-NEXT: fmul{{.*}}float +// LMTD-NEXT: fmul{{.*}}float +// LMTD-NEXT: fsub{{.*}}float +// LMTD-NEXT: fadd{{.*}}float +// +// FRTRN: alloca { float, float } +// FRTRN-NEXT: alloca { float, float } +// FRTRN-NEXT: alloca { float, float } +// FRTRN: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 0 +// FRTRN-NEXT: load float, ptr {{.*}} +// FRTRN-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 1 +// FRTRN-NEXT: load float, ptr {{.*}} +// FRTRN-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 0 +// FRTRN-NEXT: load float, ptr {{.*}} +// FRTRN-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 1 +// FRTRN-NEXT: load float +// FRTRN-NEXT: fmul{{.*}}float +// FRTRN-NEXT: fmul{{.*}}float +// FRTRN-NEXT: fmul{{.*}}float +// FRTRN-NEXT: fmul{{.*}}float +// FRTRN-NEXT: fsub{{.*}}float +// FRTRN-NEXT: fadd{{.*}}float +// +// EXTND: alloca { float, float } +// EXTND-NEXT: alloca { float, float } +// EXTND-NEXT: alloca { float, float } +// EXTND: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 0 +// EXTND-NEXT: load float, ptr +// EXTND-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 1 +// EXTND-NEXT: load float, ptr {{.*}} +// EXTND-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 0 +// EXTND-NEXT: load float, ptr {{.*}} +// EXTND-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 1 +// EXTND-NEXT: load{{.*}}float +// EXTND-NEXT: fmul{{.*}}float +// EXTND-NEXT: fmul{{.*}}float +// EXTND-NEXT: fmul{{.*}}float +// EXTND-NEXT: fmul{{.*}}float +// EXTND-NEXT: fsub{{.*}}float +// EXTND-NEXT: fadd{{.*}}float +// _Complex float mul(_Complex float a, _Complex float b) { - // LABEL: define {{.*}} @mul( - // FULL: call {{.*}} @__mulsc3 - - // LMTD: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fsub float - // LMTD-NEXT: fadd float - - // FRTRN: fmul {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fsub {{.*}}float - // FRTRN-NEXT: fadd {{.*}}float - - // LMTD-FAST: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fsub {{.*}} float - // LMTD-FAST-NEXT: fadd {{.*}} float - return a * b; } diff --git a/clang/test/CodeGen/pragma-cx-limited-range.c b/clang/test/CodeGen/pragma-cx-limited-range.c index 926da8afbee558..8fa09c9af2f7f3 100644 --- a/clang/test/CodeGen/pragma-cx-limited-range.c +++ b/clang/test/CodeGen/pragma-cx-limited-range.c @@ -8,7 +8,7 @@ // RUN: -fno-cx-limited-range -o - | FileCheck %s --check-prefix=FULL // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -complex-range=fortran -o - | FileCheck --check-prefix=FRTRN %s +// RUN: -complex-range=smith -o - | FileCheck --check-prefix=FRTRN %s // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -fno-cx-fortran-rules -o - | FileCheck --check-prefix=FULL %s diff --git a/clang/test/Driver/range.c b/clang/test/Driver/range.c index 49116df2f4480e..e63b7e527315ab 100644 --- a/clang/test/Driver/range.c +++ b/clang/test/Driver/range.c @@ -1,52 +1,93 @@ // Test range options for complex multiplication and division. -// RUN: %clang -### -target x86_64 -fcx-limited-range -c %s 2>&1 \ +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=limited -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=LMTD %s -// RUN: %clang -### -target x86_64 -fno-cx-limited-range -c %s 2>&1 \ -// RUN: | FileCheck %s - -// RUN: %clang -### -target x86_64 -fcx-limited-range -fno-cx-limited-range \ -// RUN: -c %s 2>&1 | FileCheck --check-prefix=FULL %s - -// RUN: %clang -### -target x86_64 -fcx-fortran-rules -c %s 2>&1 \ +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=smith -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=FRTRN %s -// RUN: %clang -### -target x86_64 -fno-cx-fortran-rules -c %s 2>&1 \ -// RUN: | FileCheck %s +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=extend -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=EXTND %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=full -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=FULL %s -// RUN: %clang -### -target x86_64 -fcx-limited-range \ -// RUN: -fcx-fortran-rules -c %s 2>&1 \ +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=limited \ +// RUN: -fcomplex-arithmetic=smith -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=WARN1 %s -// RUN: %clang -### -target x86_64 -fcx-fortran-rules \ -// RUN: -fcx-limited-range -c %s 2>&1 \ +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=limited \ +// RUN: -fcomplex-arithmetic=full -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=WARN2 %s -// RUN: %clang -### -target x86_64 -ffast-math -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=LMTD %s +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=limited \ +// RUN: -fcomplex-arithmetic=extend -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN3 %s -// RUN: %clang -### -target x86_64 -ffast-math -fcx-limited-range -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=LMTD %s +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=smith \ +// RUN: -fcomplex-arithmetic=limited -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN4 %s -// RUN: %clang -### -target x86_64 -fcx-limited-range -ffast-math -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=LMTD %s +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=smith \ +// RUN: -fcomplex-arithmetic=full -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN5 %s -// RUN: %clang -### -target x86_64 -ffast-math -fno-cx-limited-range -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=FULL %s +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=smith \ +// RUN: -fcomplex-arithmetic=extend -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN6 %s + + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=extend \ +// RUN: -fcomplex-arithmetic=limited -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN7 %s -// RUN: %clang -### -Werror -target x86_64 -fcx-limited-range -c %s 2>&1 \ +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=extend \ +// RUN: -fcomplex-arithmetic=smith -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN8 %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=extend \ +// RUN: -fcomplex-arithmetic=full -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN9 %s + + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=full \ +// RUN: -fcomplex-arithmetic=limited -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN10 %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=full \ +// RUN: -fcomplex-arithmetic=smith -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN11 %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=full \ +// RUN: -fcomplex-arithmetic=extend -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN12 %s + +// RUN: %clang -### -target x86_64 -ffast-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=LMTD %s -// RUN: %clang -### -Werror -target x86_64 -fcx-fortran-rules -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=FRTRN %s +// RUN: %clang -### -target x86_64 -ffast-math -fcomplex-arithmetic=limited -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=LMTD %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=limited -ffast-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=LMTD %s // LMTD: -complex-range=limited // FULL: -complex-range=full -// LMTD-NOT: -complex-range=fortran +// EXTND: -complex-range=extend +// LMTD-NOT: -complex-range=smith // CHECK-NOT: -complex-range=limited -// FRTRN: -complex-range=fortran +// FRTRN: -complex-range=smith // FRTRN-NOT: -complex-range=limited -// CHECK-NOT: -complex-range=fortran -// WARN1: warning: overriding '-fcx-limited-range' option with '-fcx-fortran-rules' [-Woverriding-option] -// WARN2: warning: overriding '-fcx-fortran-rules' option with '-fcx-limited-range' [-Woverriding-option] +// CHECK-NOT: -complex-range=smith +// WARN1: warning: overriding '-fcomplex-arithmetic=limited' option with '-fcomplex-arithmetic=smith' [-Woverriding-option] +// WARN2: warning: overriding '-fcomplex-arithmetic=limited' option with '-fcomplex-arithmetic=full' [-Woverriding-option] +// WARN3: warning: overriding '-fcomplex-arithmetic=limited' option with '-fcomplex-arithmetic=extend' [-Woverriding-option] +// WARN4: warning: overriding '-fcomplex-arithmetic=smith' option with '-fcomplex-arithmetic=limited' [-Woverriding-option] +// WARN5: warning: overriding '-fcomplex-arithmetic=smith' option with '-fcomplex-arithmetic=full' [-Woverriding-option] +// WARN6: warning: overriding '-fcomplex-arithmetic=smith' option with '-fcomplex-arithmetic=extend' [-Woverriding-option] +// WARN7: warning: overriding '-fcomplex-arithmetic=extend' option with '-fcomplex-arithmetic=limited' [-Woverriding-option] +// WARN8: warning: overriding '-fcomplex-arithmetic=extend' option with '-fcomplex-arithmetic=smith' [-Woverriding-option] +// WARN9: warning: overriding '-fcomplex-arithmetic=extend' option with '-fcomplex-arithmetic=full' [-Woverriding-option] +// WARN10: warning: overriding '-fcomplex-arithmetic=full' option with '-fcomplex-arithmetic=limited' [-Woverriding-option] +// WARN11: warning: overriding '-fcomplex-arithmetic=full' option with '-fcomplex-arithmetic=smith' [-Woverriding-option] +// WARN12: warning: overriding '-fcomplex-arithmetic=full' option with '-fcomplex-arithmetic=extend' [-Woverriding-option] _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits