https://github.com/zahiraam updated https://github.com/llvm/llvm-project/pull/70244
>From 340e3777509f70b5b300adcb181261e84247cf1a Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Mon, 23 Oct 2023 12:51:21 -0700 Subject: [PATCH 01/11] Revert "[clang] Support fixed point types in C++ (#67750)" This reverts commit a3a7d6318027bb86e6614c022e77e0bd81aef6dc. When compiling with MSVC2022 in C++32 mode this is giving an error. Compiling this simple test case: t1.cpp: with -std=c++23 will give the following error: In file included from C:\Users\zahiraam\t1.cpp:1: c:\Program files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.32215\include\vector:3329:16: error: compile with '-ffixed-point' to enable fixed point types 3329 | _Vbase _Accum = 0; | ^ c:\Program files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.32215\include\vector:3329:23: error: expected unqualified-id 3329 | _Vbase _Accum = 0; | ^ Please full error in https://github.com/llvm/llvm-project/pull/67750#issuecomment-1775264907 --- clang/include/clang/Basic/TokenKinds.def | 6 +- clang/include/clang/Driver/Options.td | 2 +- clang/lib/AST/ItaniumMangle.cpp | 59 +------------------- clang/lib/Parse/ParseExpr.cpp | 3 - clang/lib/Parse/ParseExprCXX.cpp | 9 --- clang/lib/Parse/ParseTentative.cpp | 6 -- clang/test/CodeGenCXX/fixed-point-mangle.cpp | 45 --------------- clang/test/Frontend/fixed_point_errors.cpp | 24 ++++---- 8 files changed, 15 insertions(+), 139 deletions(-) delete mode 100644 clang/test/CodeGenCXX/fixed-point-mangle.cpp diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index bbae1200d376c0d..3ce317d318f9bb6 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -423,9 +423,9 @@ C23_KEYWORD(typeof , KEYGNU) C23_KEYWORD(typeof_unqual , 0) // ISO/IEC JTC1 SC22 WG14 N1169 Extension -KEYWORD(_Accum , KEYALL) -KEYWORD(_Fract , KEYALL) -KEYWORD(_Sat , KEYALL) +KEYWORD(_Accum , KEYNOCXX) +KEYWORD(_Fract , KEYNOCXX) +KEYWORD(_Sat , KEYNOCXX) // GNU Extensions (in impl-reserved namespace) KEYWORD(_Decimal32 , KEYALL) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index e63158fb0e5333a..ca883689b05c28a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2097,7 +2097,7 @@ defm fixed_point : BoolFOption<"fixed-point", LangOpts<"FixedPoint">, DefaultFalse, PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">, NegFlag<SetFalse, [], [ClangOption], "Disable">, - BothFlags<[], [ClangOption], " fixed point types">>; + BothFlags<[], [ClangOption], " fixed point types">>, ShouldParseIf<!strconcat("!", cplusplus.KeyPath)>; defm cxx_static_destructors : BoolFOption<"c++-static-destructors", LangOpts<"RegisterStaticDestructors">, DefaultTrue, NegFlag<SetFalse, [], [ClangOption, CC1Option], diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 27e8cbf6dc3f41b..eafb121a8a4aa00 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3050,17 +3050,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { // ::= Di # char32_t // ::= Ds # char16_t // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) - // ::= [DS] DA # N1169 fixed-point [_Sat] T _Accum - // ::= [DS] DR # N1169 fixed-point [_Sat] T _Fract // ::= u <source-name> # vendor extended type - // - // <fixed-point-size> - // ::= s # short - // ::= t # unsigned short - // ::= i # plain - // ::= j # unsigned - // ::= l # long - // ::= m # unsigned long std::string type_name; // Normalize integer types as vendor extended types: // u<length>i<type size> @@ -3205,77 +3195,30 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { Out << "DF16_"; break; case BuiltinType::ShortAccum: - Out << "DAs"; - break; case BuiltinType::Accum: - Out << "DAi"; - break; case BuiltinType::LongAccum: - Out << "DAl"; - break; case BuiltinType::UShortAccum: - Out << "DAt"; - break; case BuiltinType::UAccum: - Out << "DAj"; - break; case BuiltinType::ULongAccum: - Out << "DAm"; - break; case BuiltinType::ShortFract: - Out << "DRs"; - break; case BuiltinType::Fract: - Out << "DRi"; - break; case BuiltinType::LongFract: - Out << "DRl"; - break; case BuiltinType::UShortFract: - Out << "DRt"; - break; case BuiltinType::UFract: - Out << "DRj"; - break; case BuiltinType::ULongFract: - Out << "DRm"; - break; case BuiltinType::SatShortAccum: - Out << "DSDAs"; - break; case BuiltinType::SatAccum: - Out << "DSDAi"; - break; case BuiltinType::SatLongAccum: - Out << "DSDAl"; - break; case BuiltinType::SatUShortAccum: - Out << "DSDAt"; - break; case BuiltinType::SatUAccum: - Out << "DSDAj"; - break; case BuiltinType::SatULongAccum: - Out << "DSDAm"; - break; case BuiltinType::SatShortFract: - Out << "DSDRs"; - break; case BuiltinType::SatFract: - Out << "DSDRi"; - break; case BuiltinType::SatLongFract: - Out << "DSDRl"; - break; case BuiltinType::SatUShortFract: - Out << "DSDRt"; - break; case BuiltinType::SatUFract: - Out << "DSDRj"; - break; case BuiltinType::SatULongFract: - Out << "DSDRm"; - break; + llvm_unreachable("Fixed point types are disabled for c++"); case BuiltinType::Half: Out << "Dh"; break; diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 4d267c915ff2478..dd2d9400b7747e3 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1574,9 +1574,6 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, case tok::kw_typename: case tok::kw_typeof: case tok::kw___vector: - case tok::kw__Accum: - case tok::kw__Fract: - case tok::kw__Sat: #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: #include "clang/Basic/OpenCLImageTypes.def" { diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 79db094e098f8e6..99b4931004546c1 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -2354,15 +2354,6 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { case tok::kw_bool: DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy); break; - case tok::kw__Accum: - DS.SetTypeSpecType(DeclSpec::TST_accum, Loc, PrevSpec, DiagID, Policy); - break; - case tok::kw__Fract: - DS.SetTypeSpecType(DeclSpec::TST_fract, Loc, PrevSpec, DiagID, Policy); - break; - case tok::kw__Sat: - DS.SetTypeSpecSat(Loc, PrevSpec, DiagID); - break; #define GENERIC_IMAGE_TYPE(ImgType, Id) \ case tok::kw_##ImgType##_t: \ DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \ diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index 8b653b1c4f8eaf4..28decc4fc43f9b8 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -1775,9 +1775,6 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename, case tok::kw___ibm128: case tok::kw_void: case tok::annot_decltype: - case tok::kw__Accum: - case tok::kw__Fract: - case tok::kw__Sat: #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: #include "clang/Basic/OpenCLImageTypes.def" if (NextToken().is(tok::l_paren)) @@ -1897,9 +1894,6 @@ bool Parser::isCXXDeclarationSpecifierAType() { case tok::kw_void: case tok::kw___unknown_anytype: case tok::kw___auto_type: - case tok::kw__Accum: - case tok::kw__Fract: - case tok::kw__Sat: #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: #include "clang/Basic/OpenCLImageTypes.def" return true; diff --git a/clang/test/CodeGenCXX/fixed-point-mangle.cpp b/clang/test/CodeGenCXX/fixed-point-mangle.cpp deleted file mode 100644 index 103990a61316a9c..000000000000000 --- a/clang/test/CodeGenCXX/fixed-point-mangle.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - -triple=x86_64-unknown-linux-gnu | FileCheck %s - -// Primary fixed point types -void func(signed short _Accum){} // CHECK: @_Z4funcDAs -void func(signed _Accum){} // CHECK: @_Z4funcDAi -void func(signed long _Accum){} // CHECK: @_Z4funcDAl -void func(unsigned short _Accum){} // CHECK: @_Z4funcDAt -void func(unsigned _Accum){} // CHECK: @_Z4funcDAj -void func(unsigned long _Accum){} // CHECK: @_Z4funcDAm -void func(signed short _Fract){} // CHECK: @_Z4funcDRs -void func(signed _Fract){} // CHECK: @_Z4funcDRi -void func(signed long _Fract){} // CHECK: @_Z4funcDRl -void func(unsigned short _Fract){} // CHECK: @_Z4funcDRt -void func(unsigned _Fract){} // CHECK: @_Z4funcDRj -void func(unsigned long _Fract){} // CHECK: @_Z4funcDRm - -// Aliased -void func2(short _Accum){} // CHECK: @_Z5func2DAs -void func2(_Accum){} // CHECK: @_Z5func2DAi -void func2(long _Accum){} // CHECK: @_Z5func2DAl -void func2(short _Fract){} // CHECK: @_Z5func2DRs -void func2(_Fract){} // CHECK: @_Z5func2DRi -void func2(long _Fract){} // CHECK: @_Z5func2DRl - -// Primary saturated -void func(_Sat signed short _Accum){} // CHECK: @_Z4funcDSDAs -void func(_Sat signed _Accum){} // CHECK: @_Z4funcDSDAi -void func(_Sat signed long _Accum){} // CHECK: @_Z4funcDSDAl -void func(_Sat unsigned short _Accum){} // CHECK: @_Z4funcDSDAt -void func(_Sat unsigned _Accum){} // CHECK: @_Z4funcDSDAj -void func(_Sat unsigned long _Accum){} // CHECK: @_Z4funcDSDAm -void func(_Sat signed short _Fract){} // CHECK: @_Z4funcDSDRs -void func(_Sat signed _Fract){} // CHECK: @_Z4funcDSDRi -void func(_Sat signed long _Fract){} // CHECK: @_Z4funcDSDRl -void func(_Sat unsigned short _Fract){} // CHECK: @_Z4funcDSDRt -void func(_Sat unsigned _Fract){} // CHECK: @_Z4funcDSDRj -void func(_Sat unsigned long _Fract){} // CHECK: @_Z4funcDSDRm - -// Aliased saturated -void func2(_Sat short _Accum){} // CHECK: @_Z5func2DSDAs -void func2(_Sat _Accum){} // CHECK: @_Z5func2DSDAi -void func2(_Sat long _Accum){} // CHECK: @_Z5func2DSDAl -void func2(_Sat short _Fract){} // CHECK: @_Z5func2DSDRs -void func2(_Sat _Fract){} // CHECK: @_Z5func2DSDRi -void func2(_Sat long _Fract){} // CHECK: @_Z5func2DSDRl diff --git a/clang/test/Frontend/fixed_point_errors.cpp b/clang/test/Frontend/fixed_point_errors.cpp index 2264622a2e8c870..cdd90ceb7548f94 100644 --- a/clang/test/Frontend/fixed_point_errors.cpp +++ b/clang/test/Frontend/fixed_point_errors.cpp @@ -1,18 +1,14 @@ -// RUN: %clang_cc1 -x c++ %s -verify -DWITHOUT_FIXED_POINT -// RUN: %clang_cc1 -x c++ %s -verify -ffixed-point +// RUN: %clang_cc1 -x c++ %s -verify +// RUN: %clang_cc1 -x c++ -ffixed-point %s -verify -#ifdef WITHOUT_FIXED_POINT -_Accum accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}} - // expected-error@-1{{a type specifier is required for all declarations}} -_Fract fract; // expected-error{{compile with '-ffixed-point' to enable fixed point types}} - // expected-error@-1{{a type specifier is required for all declarations}} -_Sat _Accum sat_accum; // expected-error 2{{compile with '-ffixed-point' to enable fixed point types}} - // expected-error@-1{{a type specifier is required for all declarations}} -#endif +// Name namgling is not provided for fixed point types in c++ + +_Accum accum; // expected-error{{unknown type name '_Accum'}} +_Fract fract; // expected-error{{unknown type name '_Fract'}} +_Sat _Accum sat_accum; // expected-error{{unknown type name '_Sat'}} + // expected-error@-1{{expected ';' after top level declarator}} int accum_int = 10k; // expected-error{{invalid suffix 'k' on integer constant}} int fract_int = 10r; // expected-error{{invalid suffix 'r' on integer constant}} -#ifdef WITHOUT_FIXED_POINT -float accum_flt = 0.0k; // expected-error{{invalid suffix 'k' on floating constant}} -float fract_flt = 0.0r; // expected-error{{invalid suffix 'r' on floating constant}} -#endif +float accum_flt = 10.0k; // expected-error{{invalid suffix 'k' on floating constant}} +float fract_flt = 10.0r; // expected-error{{invalid suffix 'r' on floating constant}} >From a9268af3c21a6dbb6bc70d607642cc698dbfc678 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Mon, 23 Oct 2023 14:14:42 -0700 Subject: [PATCH 02/11] Fix format. --- clang/lib/AST/ItaniumMangle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index eafb121a8a4aa00..c3be3366e66731c 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3046,7 +3046,8 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { // UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits) // UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits) // ::= Dh # IEEE 754r half-precision floating point (16 bits) - // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point type _FloatN (N bits); + // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point + // type _FloatN (N bits); // ::= Di # char32_t // ::= Ds # char16_t // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) >From 14a8ea1566c6a2d172aafdf71fbb258609fa5014 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Tue, 24 Oct 2023 05:21:58 -0700 Subject: [PATCH 03/11] Fix format. --- clang/lib/AST/ItaniumMangle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index eafb121a8a4aa00..c3be3366e66731c 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3046,7 +3046,8 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { // UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits) // UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits) // ::= Dh # IEEE 754r half-precision floating point (16 bits) - // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point type _FloatN (N bits); + // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point + // type _FloatN (N bits); // ::= Di # char32_t // ::= Ds # char16_t // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) >From 6f636b91d2acef1a4ced33d4517f300a324cd197 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Tue, 10 Oct 2023 08:31:41 -0700 Subject: [PATCH 04/11] Add support for -fcx-limited-range and #pragma CX_LIMTED_RANGE. --- clang/include/clang/Basic/FPOptions.def | 1 + clang/include/clang/Basic/LangOptions.def | 2 + clang/include/clang/Basic/TokenKinds.def | 5 ++ clang/include/clang/Driver/Options.td | 6 ++ clang/include/clang/Parse/Parser.h | 4 ++ clang/include/clang/Sema/Sema.h | 4 ++ clang/lib/CodeGen/CGExprComplex.cpp | 59 ++++++++++------ clang/lib/Driver/ToolChains/Clang.cpp | 2 + clang/lib/Parse/ParsePragma.cpp | 40 ++++++++++- clang/lib/Parse/ParseStmt.cpp | 10 +++ clang/lib/Parse/Parser.cpp | 3 + clang/lib/Sema/SemaAttr.cpp | 7 ++ clang/test/CodeGen/cx-full-range.c | 22 ++++++ clang/test/CodeGen/pragma-cx-limited-range.c | 73 ++++++++++++++++++++ clang/test/CodeGenCXX/cx-limited-range.c | 18 +++++ 15 files changed, 233 insertions(+), 23 deletions(-) create mode 100644 clang/test/CodeGen/cx-full-range.c create mode 100644 clang/test/CodeGen/pragma-cx-limited-range.c create mode 100644 clang/test/CodeGenCXX/cx-limited-range.c diff --git a/clang/include/clang/Basic/FPOptions.def b/clang/include/clang/Basic/FPOptions.def index 5b923a1944e509a..9e56d7fcf26fdcf 100644 --- a/clang/include/clang/Basic/FPOptions.def +++ b/clang/include/clang/Basic/FPOptions.def @@ -28,4 +28,5 @@ OPTION(FPEvalMethod, LangOptions::FPEvalMethodKind, 2, AllowApproxFunc) OPTION(Float16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, FPEvalMethod) OPTION(BFloat16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, Float16ExcessPrecision) OPTION(MathErrno, bool, 1, BFloat16ExcessPrecision) +OPTION(CxLimitedRange, bool, 1, MathErrno) #undef OPTION diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index c0ea4ecb9806a5b..47513522a0d7719 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -219,6 +219,8 @@ BENIGN_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization wit BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal") BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation") +LANGOPT(CxLimitedRange, 1, 0, "Enable use of algebraic expansions of complex arithmetics.") + BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars") BENIGN_LANGOPT(AccessControl , 1, 1, "C++ access control") diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 3ce317d318f9bb6..7886625e87cdf4b 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -905,6 +905,11 @@ PRAGMA_ANNOTATION(pragma_fenv_access_ms) // handles them. PRAGMA_ANNOTATION(pragma_fenv_round) +// Annotation for #pragma STDC CX_LIMITED_RANGE +// The lexer produces these so that they only take effect when the parser +// handles them. +PRAGMA_ANNOTATION(pragma_cx_limited_range) + // Annotation for #pragma float_control // The lexer produces these so that they only take effect when the parser // handles them. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index c6b1903a32a0621..2f75230f20d4fd0 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1008,6 +1008,12 @@ defm offload_uniform_block : BoolFOption<"offload-uniform-block", NegFlag<SetFalse, [], [ClangOption, CC1Option], "Don't assume">, BothFlags<[], [ClangOption], " that kernels are launched with uniform block sizes (default true for CUDA/HIP and false otherwise)">>; +def fcx_limited_range : Joined<["-"], "fcx-limited-range">, + Group<f_Group>, Visibility<[ClangOption, CC1Option]>, + HelpText<"Basic algebraic expansions of some arithmetic operations involving " + "data of type COMPLEX are disabled.">, + MarshallingInfoFlag<LangOpts<"CxLimitedRange">>; + // OpenCL-only Options def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 79ac622fd03e24e..19e205e9a418aef 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -767,6 +767,10 @@ class Parser : public CodeCompletionHandler { /// #pragma STDC FENV_ROUND... void HandlePragmaFEnvRound(); + /// Handle the annotation token produced for + /// #pragma STDC CX_LIMITED_RANGE... + void HandlePragmaCXLimitedRange(); + /// Handle the annotation token produced for /// #pragma float_control void HandlePragmaFloatControl(); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 1e9752345ffd173..a2f90b643b87bf0 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11001,6 +11001,10 @@ class Sema final { /// \#pragma STDC FENV_ACCESS void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled); + /// ActOnPragmaCXLimitedRange - Called on well formed + /// \#pragma STDC CX_LIMITED_RANGE + void ActOnPragmaCXLimitedRange(SourceLocation Loc, bool IsEnabled); + /// Called on well formed '\#pragma clang fp' that has option 'exceptions'. void ActOnPragmaFPExceptions(SourceLocation Loc, LangOptions::FPExceptionModeKind); diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index f3cbd1d0451ebe4..f18fdb17090968b 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -761,6 +761,21 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); if (Op.LHS.second && Op.RHS.second) { + // (a+ib)*(c+id) = (ac-bd)+i(bc+ad) + if (Op.FPFeatures.getCxLimitedRange() || + CGF.getLangOpts().CxLimitedRange) { + llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; + llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; + + llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // ac + llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // bd + llvm::Value *DSTr = Builder.CreateFSub(AC, BD); // ac-bd + + llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // bc + llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // ad + llvm::Value *DSTi = Builder.CreateFAdd(BC, AD); // bc+ad + return ComplexPairTy(DSTr, DSTi); + } // If both operands are complex, emit the core math directly, and then // test for NaNs. If we find NaNs in the result, we delegate to a libcall // to carefully re-compute the correct infinity representation if @@ -851,9 +866,30 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; - llvm::Value *DSTr, *DSTi; if (LHSr->getType()->isFloatingPointTy()) { + CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); + if (RHSi && (Op.FPFeatures.getCxLimitedRange() || + CGF.getLangOpts().CxLimitedRange)) { + if (!LHSi) + LHSi = llvm::Constant::getNullValue(RHSi->getType()); + + // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) + llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c + llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d + llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd + + llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c + llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d + llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd + + llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c + llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d + llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad + + DSTr = Builder.CreateFDiv(ACpBD, CCpDD); + DSTi = Builder.CreateFDiv(BCmAD, CCpDD); + } else if (RHSi && !CGF.getLangOpts().FastMath) { // If we have a complex operand on the RHS and FastMath is not allowed, we // delegate to a libcall to handle all of the complexities and minimize // underflow/overflow cases. When FastMath is allowed we construct the @@ -861,8 +897,6 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { // // FIXME: We would be able to avoid the libcall in many places if we // supported imaginary types in addition to complex types. - CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); - if (RHSi && !CGF.getLangOpts().FastMath) { BinOpInfo LibCallOp = Op; // If LHS was a real, supply a null imaginary part. if (!LHSi) @@ -884,25 +918,6 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { case llvm::Type::FP128TyID: return EmitComplexBinOpLibCall("__divtc3", LibCallOp); } - } else if (RHSi) { - if (!LHSi) - LHSi = llvm::Constant::getNullValue(RHSi->getType()); - - // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) - llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c - llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d - llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd - - llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c - llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d - llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd - - llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c - llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d - llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad - - DSTr = Builder.CreateFDiv(ACpBD, CCpDD); - DSTi = Builder.CreateFDiv(BCmAD, CCpDD); } else { assert(LHSi && "Can have at most one non-complex operand!"); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 601bbfb927746fc..4b383024eecc6c6 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2841,6 +2841,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, CmdArgs.push_back("-mlimit-float-precision"); CmdArgs.push_back(A->getValue()); } + if (const Arg *A = Args.getLastArg(options::OPT_fcx_limited_range)) + CmdArgs.push_back("-fcx-limited-range"); for (const Arg *A : Args) { auto optID = A->getOption().getID(); diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index b3178aef64d72d7..eae4b54ecfc545c 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -137,7 +137,20 @@ struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler { void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) override { tok::OnOffSwitch OOS; - PP.LexOnOffSwitch(OOS); + if (PP.LexOnOffSwitch(OOS)) + return; + + MutableArrayRef<Token> Toks( + PP.getPreprocessorAllocator().Allocate<Token>(1), 1); + + Toks[0].startToken(); + Toks[0].setKind(tok::annot_pragma_cx_limited_range); + Toks[0].setLocation(Tok.getLocation()); + Toks[0].setAnnotationEndLoc(Tok.getLocation()); + Toks[0].setAnnotationValue( + reinterpret_cast<void *>(static_cast<uintptr_t>(OOS))); + PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true, + /*IsReinject=*/false); } }; @@ -846,6 +859,31 @@ void Parser::HandlePragmaFEnvRound() { Actions.ActOnPragmaFEnvRound(PragmaLoc, RM); } +void Parser::HandlePragmaCXLimitedRange() { + assert(Tok.is(tok::annot_pragma_cx_limited_range)); + tok::OnOffSwitch OOS = static_cast<tok::OnOffSwitch>( + reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); + + bool IsEnabled; + switch (OOS) { + case tok::OOS_ON: + IsEnabled = true; + break; + case tok::OOS_OFF: + IsEnabled = false; + break; + case tok::OOS_DEFAULT: + // According to ISO C99 standard chapter 7.3.4, the default value + // for the pragma is ``off'. In GCC, the option -fcx-limited-range + // controls the default setting of the pragma. + IsEnabled = getLangOpts().CxLimitedRange ? true : false; + break; + } + + SourceLocation PragmaLoc = ConsumeAnnotationToken(); + Actions.ActOnPragmaCXLimitedRange(PragmaLoc, IsEnabled); +} + StmtResult Parser::HandlePragmaCaptured() { assert(Tok.is(tok::annot_pragma_captured)); diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 2531147c23196ae..b6c987c4b046b41 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -447,6 +447,13 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( ConsumeAnnotationToken(); return StmtError(); + case tok::annot_pragma_cx_limited_range: + ProhibitAttributes(CXX11Attrs); + Diag(Tok, diag::err_pragma_file_or_compound_scope) + << "STDC CX_LIMITED_RANGE"; + ConsumeAnnotationToken(); + return StmtError(); + case tok::annot_pragma_float_control: ProhibitAttributes(CXX11Attrs); ProhibitAttributes(GNUAttrs); @@ -1047,6 +1054,9 @@ void Parser::ParseCompoundStatementLeadingPragmas() { case tok::annot_pragma_fenv_round: HandlePragmaFEnvRound(); break; + case tok::annot_pragma_cx_limited_range: + HandlePragmaCXLimitedRange(); + break; case tok::annot_pragma_float_control: HandlePragmaFloatControl(); break; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 0f930248e77174b..befa6eba0885f29 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -836,6 +836,9 @@ Parser::ParseExternalDeclaration(ParsedAttributes &Attrs, case tok::annot_pragma_fenv_round: HandlePragmaFEnvRound(); return nullptr; + case tok::annot_pragma_cx_limited_range: + HandlePragmaCXLimitedRange(); + return nullptr; case tok::annot_pragma_float_control: HandlePragmaFloatControl(); return nullptr; diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 6dadf01ead4441b..602bc2e5ec62f3c 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -1340,6 +1340,13 @@ void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled) { CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); } +void Sema::ActOnPragmaCXLimitedRange(SourceLocation Loc, bool IsEnabled) { + FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides(); + NewFPFeatures.setCxLimitedRangeOverride(IsEnabled); + FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures); + CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); +} + void Sema::ActOnPragmaFPExceptions(SourceLocation Loc, LangOptions::FPExceptionModeKind FPE) { setExceptionMode(Loc, FPE); diff --git a/clang/test/CodeGen/cx-full-range.c b/clang/test/CodeGen/cx-full-range.c new file mode 100644 index 000000000000000..85386b84066ec6a --- /dev/null +++ b/clang/test/CodeGen/cx-full-range.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -o - | FileCheck %s --check-prefix=FULL + +_Complex float pragma_off_mul(_Complex float a, _Complex float b) { +#pragma STDC CX_LIMITED_RANGE OFF + // LABEL: define {{.*}} @pragma_on_mul + // LIMITED: %[[AC:[^ ]+]] = fmul + // LIMITED-NEXT: %[[BD:[^ ]+]] = fmul + // LIMITED-NEXT: %[[RR:[^ ]+]] = fsub + // LIMITED-NEXT: %[[BC:[^ ]+]] = fmul + // LIMITED-NEXT: %[[AD:[^ ]+]] = fmul + // LIMITED-NEXT: %[[RI:[^ ]+]] = fadd + // LIMITED: ret + return a * b; +} + +_Complex float mul(_Complex float a, _Complex float b) { + // LABEL: define {{.*}} @mul + // FULL: call {{.*}} @__mulsc3( + // FULL: ret + return a * b; +} diff --git a/clang/test/CodeGen/pragma-cx-limited-range.c b/clang/test/CodeGen/pragma-cx-limited-range.c new file mode 100644 index 000000000000000..78bed931b2ec400 --- /dev/null +++ b/clang/test/CodeGen/pragma-cx-limited-range.c @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -o - | FileCheck %s + +_Complex float pragma_on_mul(_Complex float a, _Complex float b) { +#pragma STDC CX_LIMITED_RANGE ON + // LABEL: define {{.*}} @pragma_on_mul + // CHECK: %[[AC:[^ ]+]] = fmul + // CHECK-NEXT: %[[BD:[^ ]+]] = fmul + // CHECK-NEXT: %[[RR:[^ ]+]] = fsub + // CHECK-NEXT: %[[BC:[^ ]+]] = fmul + // CHECK-NEXT: %[[AD:[^ ]+]] = fmul + // CHECK-NEXT: %[[RI:[^ ]+]] = fadd + // CHECK: ret + return a * b; +} + +_Complex float pragma_off_mul(_Complex float a, _Complex float b) { +#pragma STDC CX_LIMITED_RANGE OFF + // LABEL: define {{.*}} @pragma_off_mul + // CHECK: %[[AC:[^ ]+]] = fmul + // CHECK-NEXT: %[[BD:[^ ]+]] = fmul + // CHECK-NEXT: %[[AD:[^ ]+]] = fmul + // CHECK-NEXT: %[[BC:[^ ]+]] = fmul + // CHECK-NEXT: %[[RR:[^ ]+]] = fsub + // CHECK-NEXT: %[[RI:[^ ]+]] = fadd + // CHECK: ret + return a * b; +} + +_Complex float no_pragma_mul(_Complex float a, _Complex float b) { + // LABEL: define {{.*}} @pragma_off_mul + // CHECK: %[[AC:[^ ]+]] = fmul + // CHECK-NEXT: %[[BD:[^ ]+]] = fmul + // CHECK-NEXT: %[[AD:[^ ]+]] = fmul + // CHECK-NEXT: %[[BC:[^ ]+]] = fmul + // CHECK-NEXT: %[[RR:[^ ]+]] = fsub + // CHECK-NEXT: %[[RI:[^ ]+]] = fadd + // CHECK: ret + return a * b; +} + +_Complex float pragma_on_div(_Complex float a, _Complex float b) { +#pragma STDC CX_LIMITED_RANGE ON + // LABEL: define {{.*}} @pragma_on_div + // CHECK: [[AC:%.*]] = fmul + // CHECK: [[BD:%.*]] = fmul + // CHECK: [[ACpBD:%.*]] = fadd + // CHECK: [[CC:%.*]] = fmul + // CHECK: [[DD:%.*]] = fmul + // CHECK: [[CCpDD:%.*]] = fadd + // CHECK: [[BC:%.*]] = fmul + // CHECK: [[AD:%.*]] = fmul + // CHECK: [[BCmAD:%.*]] = fsub + // CHECK: fdiv + // CHECK: fdiv + // CHECK: ret + return a / b; +} + +_Complex float pragma_off_div(_Complex float a, _Complex float b) { +#pragma STDC CX_LIMITED_RANGE OFF + // LABEL: define {{.*}} @pragma_off_div + // CHECK: call {{.*}} @__divsc3( + // CHECK: ret + return a / b; +} + +_Complex float no_pragma_div(_Complex float a, _Complex float b) { + // LABEL: define {{.*}} @no_prama_div + // CHECK: call {{.*}} @__divsc3( + // CHECK: ret + return a / b; +} diff --git a/clang/test/CodeGenCXX/cx-limited-range.c b/clang/test/CodeGenCXX/cx-limited-range.c new file mode 100644 index 000000000000000..fce0ee413fb02c9 --- /dev/null +++ b/clang/test/CodeGenCXX/cx-limited-range.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -fcx-limited-range -o - | FileCheck %s +// RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -fuse-complex-intrinsics -fcx-range=nonan -o - | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-NO-NAN +// RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -fuse-complex-intrinsics -fcx-range=full -o - | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-FULL + +_Complex float f1(_Complex float a, _Complex float b) { +#pragma STDC CX_LIMITED_RANGE ON + // CHECK: fdiv float + // CHECK: fdiv float + return a / b; +} + +_Complex float f2(_Complex float a, _Complex float b) { +#pragma STDC CX_LIMITED_RANGE ON + // CHECK: fdiv float + // CHECK: fdiv float + return a * b; +} >From ea7caab46cee291554c52b81c7dfdf182805d00c Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Wed, 11 Oct 2023 12:28:16 -0700 Subject: [PATCH 05/11] Fix LIT test failing. --- clang/lib/CodeGen/CGExprComplex.cpp | 47 ++++++++++++------- .../cx-limited-range.c | 17 +++++-- 2 files changed, 44 insertions(+), 20 deletions(-) rename clang/test/{CodeGenCXX => CodeGen}/cx-limited-range.c (64%) diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index f18fdb17090968b..5b2d23acb410061 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -275,6 +275,8 @@ class ComplexExprEmitter ComplexPairTy EmitBinSub(const BinOpInfo &Op); ComplexPairTy EmitBinMul(const BinOpInfo &Op); ComplexPairTy EmitBinDiv(const BinOpInfo &Op); + ComplexPairTy EmitAlgebraicDiv(llvm::Value *A, llvm::Value *B, llvm::Value *C, + llvm::Value *D); ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName, const BinOpInfo &Op); @@ -861,11 +863,34 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { return ComplexPairTy(ResR, ResI); } +ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr, + llvm::Value *LHSi, + llvm::Value *RHSr, + llvm::Value *RHSi) { + llvm::Value *DSTr, *DSTi; + llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c + llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d + llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd + + llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c + llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d + llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd + + llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c + llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d + llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad + + DSTr = Builder.CreateFDiv(ACpBD, CCpDD); + DSTi = Builder.CreateFDiv(BCmAD, CCpDD); + return ComplexPairTy(DSTr, DSTi); +} + // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex // typed values. ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; + llvm::Value *DSTr, *DSTi; if (LHSr->getType()->isFloatingPointTy()) { CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); @@ -873,22 +898,7 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { CGF.getLangOpts().CxLimitedRange)) { if (!LHSi) LHSi = llvm::Constant::getNullValue(RHSi->getType()); - - // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) - llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c - llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d - llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd - - llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c - llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d - llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd - - llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c - llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d - llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad - - DSTr = Builder.CreateFDiv(ACpBD, CCpDD); - DSTi = Builder.CreateFDiv(BCmAD, CCpDD); + return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi); } else if (RHSi && !CGF.getLangOpts().FastMath) { // If we have a complex operand on the RHS and FastMath is not allowed, we // delegate to a libcall to handle all of the complexities and minimize @@ -918,6 +928,11 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { case llvm::Type::FP128TyID: return EmitComplexBinOpLibCall("__divtc3", LibCallOp); } + } else if (RHSi) { + if (!LHSi) + LHSi = llvm::Constant::getNullValue(RHSi->getType()); + + return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi); } else { assert(LHSi && "Can have at most one non-complex operand!"); diff --git a/clang/test/CodeGenCXX/cx-limited-range.c b/clang/test/CodeGen/cx-limited-range.c similarity index 64% rename from clang/test/CodeGenCXX/cx-limited-range.c rename to clang/test/CodeGen/cx-limited-range.c index fce0ee413fb02c9..91ba0b3225080ce 100644 --- a/clang/test/CodeGenCXX/cx-limited-range.c +++ b/clang/test/CodeGen/cx-limited-range.c @@ -1,18 +1,27 @@ // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -fcx-limited-range -o - | FileCheck %s + // RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -fuse-complex-intrinsics -fcx-range=nonan -o - | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-NO-NAN + // RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -fuse-complex-intrinsics -fcx-range=full -o - | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-FULL _Complex float f1(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE ON + // LABEL: define {{.*}} @f1 // CHECK: fdiv float - // CHECK: fdiv float + // CHECK-NEXT: fdiv float return a / b; } _Complex float f2(_Complex float a, _Complex float b) { -#pragma STDC CX_LIMITED_RANGE ON - // CHECK: fdiv float - // CHECK: fdiv float +#pragma STDC CX_LIMITED_RANGE OFF + // LABEL: define {{.*}} @f2 + // CHECK: %[[AC:[^ ]+]] = fmul + // CHECK-NEXT: %[[BD:[^ ]+]] = fmul + // CHECK-NEXT: %[[RR:[^ ]+]] = fsub + // CHECK-NEXT: %[[BC:[^ ]+]] = fmul + // CHECK-NEXT: %[[AD:[^ ]+]] = fmul + // CHECK-NEXT: %[[RI:[^ ]+]] = fadd + // CHECK: ret return a * b; } >From 8b0af1094815452d42aac38224124ee8a2d0426a Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Mon, 16 Oct 2023 12:17:31 -0700 Subject: [PATCH 06/11] Fixed LIT test and added fno-cx-limited-range. --- clang/include/clang/Driver/Options.td | 8 +- clang/lib/Driver/ToolChains/Clang.cpp | 2 + clang/test/CodeGen/cx-limited-range.c | 27 ++--- clang/test/CodeGen/pragma-cx-limited-range.c | 118 +++++++++++-------- 4 files changed, 87 insertions(+), 68 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 2f75230f20d4fd0..45cb7567e0eeb71 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1010,9 +1010,13 @@ defm offload_uniform_block : BoolFOption<"offload-uniform-block", def fcx_limited_range : Joined<["-"], "fcx-limited-range">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Basic algebraic expansions of some arithmetic operations involving " - "data of type COMPLEX are disabled.">, + HelpText<"Basic algebraic expansions of complex arithmetic operations " + "involving are enabled.">, MarshallingInfoFlag<LangOpts<"CxLimitedRange">>; +def fno_cx_limited_range : Joined<["-"], "fno-cx-limited-range">, + Group<f_Group>, Visibility<[ClangOption, CC1Option]>, + HelpText<"Basic algebraic expansions of complex arithmetic operations " + "involving are enabled.">; // OpenCL-only Options def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 4b383024eecc6c6..0a5f785d56915a2 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2843,6 +2843,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, } if (const Arg *A = Args.getLastArg(options::OPT_fcx_limited_range)) CmdArgs.push_back("-fcx-limited-range"); + if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_limited_range)) + CmdArgs.push_back("-fno-cx-limited-range"); for (const Arg *A : Args) { auto optID = A->getOption().getID(); diff --git a/clang/test/CodeGen/cx-limited-range.c b/clang/test/CodeGen/cx-limited-range.c index 91ba0b3225080ce..d4d40a563139925 100644 --- a/clang/test/CodeGen/cx-limited-range.c +++ b/clang/test/CodeGen/cx-limited-range.c @@ -1,27 +1,20 @@ // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -fcx-limited-range -o - | FileCheck %s -// RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -fuse-complex-intrinsics -fcx-range=nonan -o - | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-NO-NAN - -// RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -fuse-complex-intrinsics -fcx-range=full -o - | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-FULL - _Complex float f1(_Complex float a, _Complex float b) { -#pragma STDC CX_LIMITED_RANGE ON // LABEL: define {{.*}} @f1 - // CHECK: fdiv float - // CHECK-NEXT: fdiv float - return a / b; + // CHECK: fmul + // CHECK-NEXT: fmul + // CHECK-NEXT: fsub + // CHECK-NEXT: fmul + // CHECK-NEXT: fmul + // CHECK-NEXT: fadd + return a * b; } _Complex float f2(_Complex float a, _Complex float b) { -#pragma STDC CX_LIMITED_RANGE OFF // LABEL: define {{.*}} @f2 - // CHECK: %[[AC:[^ ]+]] = fmul - // CHECK-NEXT: %[[BD:[^ ]+]] = fmul - // CHECK-NEXT: %[[RR:[^ ]+]] = fsub - // CHECK-NEXT: %[[BC:[^ ]+]] = fmul - // CHECK-NEXT: %[[AD:[^ ]+]] = fmul - // CHECK-NEXT: %[[RI:[^ ]+]] = fadd - // CHECK: ret - return a * b; + // CHECK: fdiv float + // CHECK-NEXT: fdiv 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 78bed931b2ec400..9afbb9cf741d55a 100644 --- a/clang/test/CodeGen/pragma-cx-limited-range.c +++ b/clang/test/CodeGen/pragma-cx-limited-range.c @@ -1,73 +1,93 @@ // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -o - | FileCheck %s +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -fcx-limited-range -o - | FileCheck --check-prefix=OPT-CXLMT %s + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -fno-cx-limited-range -o - | FileCheck %s + _Complex float pragma_on_mul(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE ON - // LABEL: define {{.*}} @pragma_on_mul - // CHECK: %[[AC:[^ ]+]] = fmul - // CHECK-NEXT: %[[BD:[^ ]+]] = fmul - // CHECK-NEXT: %[[RR:[^ ]+]] = fsub - // CHECK-NEXT: %[[BC:[^ ]+]] = fmul - // CHECK-NEXT: %[[AD:[^ ]+]] = fmul - // CHECK-NEXT: %[[RI:[^ ]+]] = fadd - // CHECK: ret + // CHECK-LABEL: define {{.*}} @pragma_on_mul( + // CHECK: fmul float + // CHECK-NEXT: fmul float + // CHECK-NEXT: fsub float + // CHECK-NEXT: fmul float + // CHECK-NEXT: fmul float + // CHECK-NEXT: fadd float + + // OPT-CXLMT-LABEL: define {{.*}} @pragma_on_mul( + // OPT-CXLMT: fmul float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fsub float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fadd float return a * b; } _Complex float pragma_off_mul(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE OFF - // LABEL: define {{.*}} @pragma_off_mul - // CHECK: %[[AC:[^ ]+]] = fmul - // CHECK-NEXT: %[[BD:[^ ]+]] = fmul - // CHECK-NEXT: %[[AD:[^ ]+]] = fmul - // CHECK-NEXT: %[[BC:[^ ]+]] = fmul - // CHECK-NEXT: %[[RR:[^ ]+]] = fsub - // CHECK-NEXT: %[[RI:[^ ]+]] = fadd - // CHECK: ret - return a * b; -} + // CHECK-LABEL: define {{.*}} @pragma_off_mul( + // CHECK: call {{.*}} @__mulsc3 -_Complex float no_pragma_mul(_Complex float a, _Complex float b) { - // LABEL: define {{.*}} @pragma_off_mul - // CHECK: %[[AC:[^ ]+]] = fmul - // CHECK-NEXT: %[[BD:[^ ]+]] = fmul - // CHECK-NEXT: %[[AD:[^ ]+]] = fmul - // CHECK-NEXT: %[[BC:[^ ]+]] = fmul - // CHECK-NEXT: %[[RR:[^ ]+]] = fsub - // CHECK-NEXT: %[[RI:[^ ]+]] = fadd - // CHECK: ret + // OPT-CXLMT-LABEL: define {{.*}} @pragma_off_mul( + // OPT-CXLMT: fmul float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fsub float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fadd float return a * b; } _Complex float pragma_on_div(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE ON - // LABEL: define {{.*}} @pragma_on_div - // CHECK: [[AC:%.*]] = fmul - // CHECK: [[BD:%.*]] = fmul - // CHECK: [[ACpBD:%.*]] = fadd - // CHECK: [[CC:%.*]] = fmul - // CHECK: [[DD:%.*]] = fmul - // CHECK: [[CCpDD:%.*]] = fadd - // CHECK: [[BC:%.*]] = fmul - // CHECK: [[AD:%.*]] = fmul - // CHECK: [[BCmAD:%.*]] = fsub - // CHECK: fdiv - // CHECK: fdiv - // CHECK: ret + // CHECK-LABEL: define {{.*}} @pragma_on_div( + // CHECK: fmul float + // CHECK-NEXT: fmul float + // CHECK-NEXT: fadd float + // CHECK-NEXT: fmul float + // CHECK-NEXT: fmul float + // CHECK-NEXT: fadd float + // CHECK-NEXT: fmul float + // CHECK-NEXT: fmul float + // CHECK-NEXT: fsub float + // CHECK-NEXT: fdiv float + // CHECK: fdiv float + + // OPT-CXLMT-LABEL: define {{.*}} @pragma_on_div( + // OPT-CXLMT: fmul float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fadd float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fadd float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fsub float + // OPT-CXLMT-NEXT: fdiv float + // OPT-CXLMT-NEXT: fdiv float return a / b; } _Complex float pragma_off_div(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE OFF - // LABEL: define {{.*}} @pragma_off_div - // CHECK: call {{.*}} @__divsc3( - // CHECK: ret - return a / b; -} + // CHECK-LABEL: define {{.*}} @pragma_off_div( + // CHECK: call {{.*}} @__divsc3 -_Complex float no_pragma_div(_Complex float a, _Complex float b) { - // LABEL: define {{.*}} @no_prama_div - // CHECK: call {{.*}} @__divsc3( - // CHECK: ret + // OPT-CXLMT-LABEL: define {{.*}} @pragma_off_div( + // OPT-CXLMT: fmul float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fadd float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fadd float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fmul float + // OPT-CXLMT-NEXT: fsub float + // OPT-CXLMT-NEXT: fdiv float + // OPT-CXLMT-NEXT: fdiv float return a / b; } >From f36341192a21f820146b780ef00dfa02f5df1b37 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Wed, 18 Oct 2023 07:06:35 -0700 Subject: [PATCH 07/11] Fixed a few things. --- clang/include/clang/Basic/FPOptions.def | 1 + clang/include/clang/Basic/LangOptions.def | 1 + clang/include/clang/Driver/Options.td | 7 +++++ clang/lib/CodeGen/CGExprComplex.cpp | 29 ++++++++++++++++- clang/lib/Driver/ToolChains/Clang.cpp | 38 ++++++++++++++++++++--- 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/FPOptions.def b/clang/include/clang/Basic/FPOptions.def index 9e56d7fcf26fdcf..b633004386eb0c2 100644 --- a/clang/include/clang/Basic/FPOptions.def +++ b/clang/include/clang/Basic/FPOptions.def @@ -29,4 +29,5 @@ OPTION(Float16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, FPEvalMethod OPTION(BFloat16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, Float16ExcessPrecision) OPTION(MathErrno, bool, 1, BFloat16ExcessPrecision) OPTION(CxLimitedRange, bool, 1, MathErrno) +OPTION(CxFortranRules, bool, 1, CxLimitedRange) #undef OPTION diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 47513522a0d7719..5ac0b9143e22331 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -220,6 +220,7 @@ BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal") BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation") LANGOPT(CxLimitedRange, 1, 0, "Enable use of algebraic expansions of complex arithmetics.") +LANGOPT(CxFortranRules, 1, 0, "Enable use of range reduction for complex arithmetics.") BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 45cb7567e0eeb71..80e78e938e51edb 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1017,6 +1017,13 @@ def fno_cx_limited_range : Joined<["-"], "fno-cx-limited-range">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>, HelpText<"Basic algebraic expansions of complex arithmetic operations " "involving are enabled.">; +def fcx_fortran_rules : Joined<["-"], "fcx-fortran-rules">, + Group<f_Group>, Visibility<[ClangOption, CC1Option]>, + HelpText<"Range reduction is enabled for complex arithmetic operations.">, + MarshallingInfoFlag<LangOpts<"CxFortranRules">>; +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.">; // OpenCL-only Options def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 5b2d23acb410061..2a82b9ccde85757 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -277,6 +277,8 @@ class ComplexExprEmitter ComplexPairTy EmitBinDiv(const BinOpInfo &Op); ComplexPairTy EmitAlgebraicDiv(llvm::Value *A, llvm::Value *B, llvm::Value *C, llvm::Value *D); + ComplexPairTy EmitRangeReductionDiv(llvm::Value *A, llvm::Value *B, + llvm::Value *C, llvm::Value *D); ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName, const BinOpInfo &Op); @@ -867,6 +869,7 @@ ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr, llvm::Value *LHSi, llvm::Value *RHSr, llvm::Value *RHSi) { + // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) llvm::Value *DSTr, *DSTi; llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d @@ -885,6 +888,28 @@ ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr, return ComplexPairTy(DSTr, DSTi); } +ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr, + llvm::Value *LHSi, + llvm::Value *RHSr, + llvm::Value *RHSi) { + llvm::Value *DSTr, *DSTi; + llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c + llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d + llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd + + llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c + llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d + llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd + + llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c + llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d + llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad + + DSTr = Builder.CreateFDiv(ACpBD, CCpDD); + DSTi = Builder.CreateFDiv(BCmAD, CCpDD); + return ComplexPairTy(DSTr, DSTi); +} + // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex // typed values. ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { @@ -894,7 +919,9 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { llvm::Value *DSTr, *DSTi; if (LHSr->getType()->isFloatingPointTy()) { CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); - if (RHSi && (Op.FPFeatures.getCxLimitedRange() || + if (RHSi && CGF.getLangOpts().CxFortranRules) { + return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi); + } else if (RHSi && (Op.FPFeatures.getCxLimitedRange() || CGF.getLangOpts().CxLimitedRange)) { if (!LHSi) LHSi = llvm::Constant::getNullValue(RHSi->getType()); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 0a5f785d56915a2..f10912d772bd6c8 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2836,15 +2836,14 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, bool StrictFPModel = false; StringRef Float16ExcessPrecision = ""; StringRef BFloat16ExcessPrecision = ""; + StringRef CxLimitedRange = "NoCxLimiteRange"; + StringRef CxFortranRules = "NoCxFortranRules"; + StringRef Range = ""; if (const Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) { CmdArgs.push_back("-mlimit-float-precision"); CmdArgs.push_back(A->getValue()); } - if (const Arg *A = Args.getLastArg(options::OPT_fcx_limited_range)) - CmdArgs.push_back("-fcx-limited-range"); - if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_limited_range)) - CmdArgs.push_back("-fno-cx-limited-range"); for (const Arg *A : Args) { auto optID = A->getOption().getID(); @@ -2852,6 +2851,28 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, switch (optID) { default: break; + case options::OPT_fcx_limited_range: { + if (Range == "") + Range = "CxLimitedRange"; + else + D.Diag(clang::diag::err_drv_incompatible_options) + << "fcx-limited-range" << Range; + break; + } + case options::OPT_fno_cx_limited_range: + Range = "NoCxLimitedRange"; + break; + case options::OPT_fcx_fortran_rules: { + if (Range == "") + Range = "CxFortranRules"; + else + D.Diag(clang::diag::err_drv_incompatible_options) + << "fcx-fortan-rules" << Range; + break; + } + case options::OPT_fno_cx_fortran_rules: + CxFortranRules = "NoCxFortranRules"; + break; case options::OPT_ffp_model_EQ: { // If -ffp-model= is seen, reset to fno-fast-math HonorINFs = true; @@ -3273,6 +3294,15 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, if (Args.hasFlag(options::OPT_fno_strict_float_cast_overflow, options::OPT_fstrict_float_cast_overflow, false)) CmdArgs.push_back("-fno-strict-float-cast-overflow"); + + if (const Arg *A = Args.getLastArg(options::OPT_fcx_limited_range)) + CmdArgs.push_back("-fcx-limited-range"); + if (const Arg *A = Args.getLastArg(options::OPT_fcx_fortran_rules)) + CmdArgs.push_back("-fcx-fortran-rules"); + if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_limited_range)) + CmdArgs.push_back("-fno-cx-limited-range"); + if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_fortran_rules)) + CmdArgs.push_back("-fno-cx-fortran-rules"); } static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs, >From 2aa766352db0c3010991b4bc53ded7a2d1693bfd Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Wed, 25 Oct 2023 10:51:04 -0700 Subject: [PATCH 08/11] Fixed a few things. --- clang/lib/CodeGen/CGExprComplex.cpp | 105 +++++++--- clang/lib/Parse/ParsePragma.cpp | 6 +- clang/test/CodeGen/cx-complex-range.c | 79 ++++++++ clang/test/CodeGen/cx-full-range.c | 22 --- clang/test/CodeGen/cx-limited-range.c | 20 -- clang/test/CodeGen/pragma-cx-limited-range.c | 193 ++++++++++++------- 6 files changed, 287 insertions(+), 138 deletions(-) create mode 100644 clang/test/CodeGen/cx-complex-range.c delete mode 100644 clang/test/CodeGen/cx-full-range.c delete mode 100644 clang/test/CodeGen/cx-limited-range.c diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 2a82b9ccde85757..4b559a5dc747962 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -871,7 +871,8 @@ ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr, llvm::Value *RHSi) { // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) llvm::Value *DSTr, *DSTi; - llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c + + llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd @@ -888,26 +889,79 @@ ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr, return ComplexPairTy(DSTr, DSTi); } +/// EmitFAbs - Emit a call to @llvm.fabs. +static llvm::Value *EmitllvmFAbs(CodeGenFunction &CGF, llvm::Value *Value) { + llvm::Function *Func = + CGF.CGM.getIntrinsic(llvm::Intrinsic::fabs, Value->getType()); + llvm::Value *Call = CGF.Builder.CreateCall(Func, Value); + return Call; +} + ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr, llvm::Value *LHSi, llvm::Value *RHSr, llvm::Value *RHSi) { - llvm::Value *DSTr, *DSTi; - llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c - llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d - llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd - - llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c - llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d - llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd - - llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c - llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d - llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad - - DSTr = Builder.CreateFDiv(ACpBD, CCpDD); - DSTi = Builder.CreateFDiv(BCmAD, CCpDD); - return ComplexPairTy(DSTr, DSTi); + // (a + ib) / (c + id) = (e + if) + llvm::Value *FAbsRHSr = EmitllvmFAbs(CGF, RHSr); // |c| + llvm::Value *FAbsRHSi = EmitllvmFAbs(CGF, RHSi); // |d| + // |c| >= |d| + llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi, "abs_cmp"); + + llvm::BasicBlock *TrueBB = CGF.createBasicBlock("true_bb_name"); + llvm::BasicBlock *FalseBB = CGF.createBasicBlock("false_bb_name"); + llvm::BasicBlock *ContBB = CGF.createBasicBlock("cont_bb"); + Builder.CreateCondBr(IsR, TrueBB, FalseBB); + + CGF.EmitBlock(TrueBB); + // abs(c) >= abs(d) + // r = d/c + // tmp = c + rd + // e = (a + br)/tmp + // f = (b - ar)/tmp + llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr); // d/c + + llvm::Value *RD = Builder.CreateFMul(DdC, RHSi); // (d/c)d + llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD); // c+((d/c)d) + + llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC); // b(d/c) + llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3); // a+b(d/c) + llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD); // (a+b(d/c))/(c+(d/c)d) + + llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC); // ar + llvm::Value *T6 = Builder.CreateFSub(LHSi, T5); // b-ar + llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD); // (b-a(d/c))/(c+(d/c)d) + Builder.CreateBr(ContBB); + + CGF.EmitBlock(FalseBB); + // abs(c) < abs(d) + // r = c/d + // tmp = d + rc + // e = (ar + b)/tmp + // f = (br - a)/tmp + llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi); // c/d + + llvm::Value *RC = Builder.CreateFMul(CdD, RHSr); // (c/d)c + llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC); // d+(c/d)c + + llvm::Value *T7 = Builder.CreateFAdd(CdD, RHSi); // (c/d)+b + llvm::Value *T8 = Builder.CreateFMul(LHSr, T7); // a((c/d)+b) + llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC); // (a((c/d)+b)/(d+(c/d)c)) + + llvm::Value *T9 = Builder.CreateFSub(CdD, LHSr); // (c/d)-a + llvm::Value *T10 = Builder.CreateFMul(RHSi, T9); // b((c/d)-a) + llvm::Value *DSTFi = + Builder.CreateFDiv(T10, DpRC); // (b((c/d)-a))/(d+(c/d)c)) + Builder.CreateBr(ContBB); + + // Phi together the computation paths. + CGF.EmitBlock(ContBB); + llvm::PHINode *VALr = Builder.CreatePHI(DSTTr->getType(), 2); + VALr->addIncoming(DSTTr, TrueBB); + VALr->addIncoming(DSTFr, FalseBB); + llvm::PHINode *VALi = Builder.CreatePHI(DSTTi->getType(), 2); + VALi->addIncoming(DSTTi, TrueBB); + VALi->addIncoming(DSTFi, FalseBB); + return ComplexPairTy(VALr, VALi); } // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex @@ -919,7 +973,8 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { llvm::Value *DSTr, *DSTi; if (LHSr->getType()->isFloatingPointTy()) { CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); - if (RHSi && CGF.getLangOpts().CxFortranRules) { + if (RHSi && CGF.getLangOpts().CxFortranRules && + !Op.FPFeatures.getCxLimitedRange()) { return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi); } else if (RHSi && (Op.FPFeatures.getCxLimitedRange() || CGF.getLangOpts().CxLimitedRange)) { @@ -927,13 +982,13 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { LHSi = llvm::Constant::getNullValue(RHSi->getType()); return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi); } else if (RHSi && !CGF.getLangOpts().FastMath) { - // If we have a complex operand on the RHS and FastMath is not allowed, we - // delegate to a libcall to handle all of the complexities and minimize - // underflow/overflow cases. When FastMath is allowed we construct the - // divide inline using the same algorithm as for integer operands. - // - // FIXME: We would be able to avoid the libcall in many places if we - // supported imaginary types in addition to complex types. + // If we have a complex operand on the RHS and FastMath is not allowed, we + // delegate to a libcall to handle all of the complexities and minimize + // underflow/overflow cases. When FastMath is allowed we construct the + // divide inline using the same algorithm as for integer operands. + // + // FIXME: We would be able to avoid the libcall in many places if we + // supported imaginary types in addition to complex types. BinOpInfo LibCallOp = Op; // If LHS was a real, supply a null imaginary part. if (!LHSi) diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index eae4b54ecfc545c..6e4db5da9fdbc49 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -873,9 +873,9 @@ void Parser::HandlePragmaCXLimitedRange() { IsEnabled = false; break; case tok::OOS_DEFAULT: - // According to ISO C99 standard chapter 7.3.4, the default value - // for the pragma is ``off'. In GCC, the option -fcx-limited-range - // controls the default setting of the pragma. + // According to ISO C99 standard chapter 7.3.4, the default value + // for the pragma is ``off'. In GCC, the option -fcx-limited-range + // controls the default setting of the pragma. IsEnabled = getLangOpts().CxLimitedRange ? true : false; break; } diff --git a/clang/test/CodeGen/cx-complex-range.c b/clang/test/CodeGen/cx-complex-range.c new file mode 100644 index 000000000000000..921abd74ecbb631 --- /dev/null +++ b/clang/test/CodeGen/cx-complex-range.c @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -o - | FileCheck %s --check-prefix=FULL + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -fcx-limited-range -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: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -fcx-fortran-rules -o - | FileCheck %s --check-prefix=FRTRN + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -fno-cx-fortran-rules -o - | FileCheck %s --check-prefix=FULL + +_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: true_bb_name: + // 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: false_bb_name: + // FRTRN-NEXT: fdiv float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fadd float + // FRTRN-NEXT: fadd float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fdiv float + // FRTRN-NEXT: fsub float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fdiv float + // FRTRN-NEXT: br label + // FRTRN: cont_bb: + // FRTRN-NEXT: phi float + // FRTRN-NEXT: phi float + + return a / b; +} + +_Complex float mul(_Complex float a, _Complex float b) { + // LABEL: define {{.*}} @mul( + // FULL: call {{.*}} @__mulsc3 + + // LMTD: fmul float + // LMTD-NEXT: fmul float + // LMTD-NEXT: fsub float + // LMTD-NEXT: fmul float + // LMTD-NEXT: fmul float + // LMTD-NEXT: fadd float + + // FRTRN: call <2 x float> @__mulsc3 + + return a * b; +} diff --git a/clang/test/CodeGen/cx-full-range.c b/clang/test/CodeGen/cx-full-range.c deleted file mode 100644 index 85386b84066ec6a..000000000000000 --- a/clang/test/CodeGen/cx-full-range.c +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -o - | FileCheck %s --check-prefix=FULL - -_Complex float pragma_off_mul(_Complex float a, _Complex float b) { -#pragma STDC CX_LIMITED_RANGE OFF - // LABEL: define {{.*}} @pragma_on_mul - // LIMITED: %[[AC:[^ ]+]] = fmul - // LIMITED-NEXT: %[[BD:[^ ]+]] = fmul - // LIMITED-NEXT: %[[RR:[^ ]+]] = fsub - // LIMITED-NEXT: %[[BC:[^ ]+]] = fmul - // LIMITED-NEXT: %[[AD:[^ ]+]] = fmul - // LIMITED-NEXT: %[[RI:[^ ]+]] = fadd - // LIMITED: ret - return a * b; -} - -_Complex float mul(_Complex float a, _Complex float b) { - // LABEL: define {{.*}} @mul - // FULL: call {{.*}} @__mulsc3( - // FULL: ret - return a * b; -} diff --git a/clang/test/CodeGen/cx-limited-range.c b/clang/test/CodeGen/cx-limited-range.c deleted file mode 100644 index d4d40a563139925..000000000000000 --- a/clang/test/CodeGen/cx-limited-range.c +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fcx-limited-range -o - | FileCheck %s - -_Complex float f1(_Complex float a, _Complex float b) { - // LABEL: define {{.*}} @f1 - // CHECK: fmul - // CHECK-NEXT: fmul - // CHECK-NEXT: fsub - // CHECK-NEXT: fmul - // CHECK-NEXT: fmul - // CHECK-NEXT: fadd - return a * b; -} - -_Complex float f2(_Complex float a, _Complex float b) { - // LABEL: define {{.*}} @f2 - // CHECK: fdiv float - // CHECK-NEXT: fdiv 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 9afbb9cf741d55a..9490750e6e85c71 100644 --- a/clang/test/CodeGen/pragma-cx-limited-range.c +++ b/clang/test/CodeGen/pragma-cx-limited-range.c @@ -1,93 +1,150 @@ // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -o - | FileCheck %s +// RUN: -o - | FileCheck %s --check-prefix=FULL // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fcx-limited-range -o - | FileCheck --check-prefix=OPT-CXLMT %s +// RUN: -fcx-limited-range -o - | FileCheck --check-prefix=LMTD %s // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fno-cx-limited-range -o - | FileCheck %s +// RUN: -fno-cx-limited-range -o - | FileCheck %s --check-prefix=FULL + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -fcx-fortran-rules -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 _Complex float pragma_on_mul(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE ON - // CHECK-LABEL: define {{.*}} @pragma_on_mul( - // CHECK: fmul float - // CHECK-NEXT: fmul float - // CHECK-NEXT: fsub float - // CHECK-NEXT: fmul float - // CHECK-NEXT: fmul float - // CHECK-NEXT: fadd float - - // OPT-CXLMT-LABEL: define {{.*}} @pragma_on_mul( - // OPT-CXLMT: fmul float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fsub float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fadd float + // LABEL: define {{.*}} @pragma_on_mul( + // FULL: fmul float + // FULL-NEXT: fmul float + // FULL-NEXT: fsub float + // FULL-NEXT: fmul float + // FULL-NEXT: fmul float + // FULL-NEXT: fadd float + + // LMTD: fmul float + // LMTD-NEXT: fmul float + // LMTD-NEXT: fsub float + // LMTD-NEXT: fmul float + // LMTD-NEXT: fmul float + // LMTD-NEXT: fadd float + + // FRTRN: fmul float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fsub float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fadd float + return a * b; } _Complex float pragma_off_mul(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE OFF - // CHECK-LABEL: define {{.*}} @pragma_off_mul( - // CHECK: call {{.*}} @__mulsc3 - - // OPT-CXLMT-LABEL: define {{.*}} @pragma_off_mul( - // OPT-CXLMT: fmul float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fsub float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fadd float + // LABEL: define {{.*}} @pragma_off_mul( + // FULL: call {{.*}} @__mulsc3 + + // LMTD: fmul float + // LMTD-NEXT: fmul float + // LMTD-NEXT: fsub float + // LMTD-NEXT: fmul float + // LMTD-NEXT: fmul float + // LMTD-NEXT: fadd float + + // FRTRN: call {{.*}} @__mulsc3 + return a * b; } _Complex float pragma_on_div(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE ON - // CHECK-LABEL: define {{.*}} @pragma_on_div( - // CHECK: fmul float - // CHECK-NEXT: fmul float - // CHECK-NEXT: fadd float - // CHECK-NEXT: fmul float - // CHECK-NEXT: fmul float - // CHECK-NEXT: fadd float - // CHECK-NEXT: fmul float - // CHECK-NEXT: fmul float - // CHECK-NEXT: fsub float - // CHECK-NEXT: fdiv float - // CHECK: fdiv float - - // OPT-CXLMT-LABEL: define {{.*}} @pragma_on_div( - // OPT-CXLMT: fmul float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fadd float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fadd float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fsub float - // OPT-CXLMT-NEXT: fdiv float - // OPT-CXLMT-NEXT: fdiv float + // LABEL: define {{.*}} @pragma_on_div( + // FULL: fmul float + // FULL-NEXT: fmul float + // FULL-NEXT: fadd float + // FULL-NEXT: fmul float + // FULL-NEXT: fmul float + // FULL-NEXT: fadd float + // FULL-NEXT: fmul float + // FULL-NEXT: fmul float + // FULL-NEXT: fsub float + // FULL-NEXT: fdiv float + // FULL: fdiv float + + // 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: fmul float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fadd float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fadd float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fsub float + // FRTRN-NEXT: fdiv float + // FRTRN-NEXT: fdiv float + return a / b; } _Complex float pragma_off_div(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE OFF - // CHECK-LABEL: define {{.*}} @pragma_off_div( - // CHECK: call {{.*}} @__divsc3 - - // OPT-CXLMT-LABEL: define {{.*}} @pragma_off_div( - // OPT-CXLMT: fmul float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fadd float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fadd float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fmul float - // OPT-CXLMT-NEXT: fsub float - // OPT-CXLMT-NEXT: fdiv float - // OPT-CXLMT-NEXT: fdiv float + // LABEL: define {{.*}} @pragma_off_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: true_bb_name: + // 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: false_bb_name: + // FRTRN-NEXT: fdiv float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fadd float + // FRTRN-NEXT: fadd float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fdiv float + // FRTRN-NEXT: fsub float + // FRTRN-NEXT: fmul float + // FRTRN-NEXT: fdiv float + // FRTRN-NEXT: br label + // FRTRN: cont_bb: + // FRTRN-NEXT: phi float + // FRTRN-NEXT: phi float + return a / b; } >From a616aaeea9f6e7fcdbf561f1e389c3ad736e9350 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Wed, 25 Oct 2023 12:28:11 -0700 Subject: [PATCH 09/11] Fix format. --- clang/lib/CodeGen/CGExprComplex.cpp | 22 +++++++++++----------- clang/lib/Driver/ToolChains/Clang.cpp | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 4b559a5dc747962..f73dd0538e78751 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -920,8 +920,8 @@ ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr, // f = (b - ar)/tmp llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr); // d/c - llvm::Value *RD = Builder.CreateFMul(DdC, RHSi); // (d/c)d - llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD); // c+((d/c)d) + llvm::Value *RD = Builder.CreateFMul(DdC, RHSi); // (d/c)d + llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD); // c+((d/c)d) llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC); // b(d/c) llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3); // a+b(d/c) @@ -938,17 +938,17 @@ ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr, // tmp = d + rc // e = (ar + b)/tmp // f = (br - a)/tmp - llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi); // c/d + llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi); // c/d - llvm::Value *RC = Builder.CreateFMul(CdD, RHSr); // (c/d)c - llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC); // d+(c/d)c + llvm::Value *RC = Builder.CreateFMul(CdD, RHSr); // (c/d)c + llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC); // d+(c/d)c - llvm::Value *T7 = Builder.CreateFAdd(CdD, RHSi); // (c/d)+b - llvm::Value *T8 = Builder.CreateFMul(LHSr, T7); // a((c/d)+b) - llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC); // (a((c/d)+b)/(d+(c/d)c)) + llvm::Value *T7 = Builder.CreateFAdd(CdD, RHSi); // (c/d)+b + llvm::Value *T8 = Builder.CreateFMul(LHSr, T7); // a((c/d)+b) + llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC); // (a((c/d)+b)/(d+(c/d)c)) - llvm::Value *T9 = Builder.CreateFSub(CdD, LHSr); // (c/d)-a - llvm::Value *T10 = Builder.CreateFMul(RHSi, T9); // b((c/d)-a) + llvm::Value *T9 = Builder.CreateFSub(CdD, LHSr); // (c/d)-a + llvm::Value *T10 = Builder.CreateFMul(RHSi, T9); // b((c/d)-a) llvm::Value *DSTFi = Builder.CreateFDiv(T10, DpRC); // (b((c/d)-a))/(d+(c/d)c)) Builder.CreateBr(ContBB); @@ -977,7 +977,7 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { !Op.FPFeatures.getCxLimitedRange()) { return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi); } else if (RHSi && (Op.FPFeatures.getCxLimitedRange() || - CGF.getLangOpts().CxLimitedRange)) { + CGF.getLangOpts().CxLimitedRange)) { if (!LHSi) LHSi = llvm::Constant::getNullValue(RHSi->getType()); return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index f10912d772bd6c8..b915062bd59734c 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3296,11 +3296,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, CmdArgs.push_back("-fno-strict-float-cast-overflow"); if (const Arg *A = Args.getLastArg(options::OPT_fcx_limited_range)) - CmdArgs.push_back("-fcx-limited-range"); + CmdArgs.push_back("-fcx-limited-range"); if (const Arg *A = Args.getLastArg(options::OPT_fcx_fortran_rules)) CmdArgs.push_back("-fcx-fortran-rules"); if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_limited_range)) - CmdArgs.push_back("-fno-cx-limited-range"); + CmdArgs.push_back("-fno-cx-limited-range"); if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_fortran_rules)) CmdArgs.push_back("-fno-cx-fortran-rules"); } >From 2898d3078f552b35130eceeb60f0bc796dcf420b Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Wed, 25 Oct 2023 12:56:18 -0700 Subject: [PATCH 10/11] Fix format again. --- clang/lib/Driver/ToolChains/Clang.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index b915062bd59734c..ca414b1956f5b02 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3295,14 +3295,14 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, options::OPT_fstrict_float_cast_overflow, false)) CmdArgs.push_back("-fno-strict-float-cast-overflow"); - if (const Arg *A = Args.getLastArg(options::OPT_fcx_limited_range)) + if (const Arg *A = Args.getLastArg(options::OPT_fcx_limited_range)) CmdArgs.push_back("-fcx-limited-range"); - if (const Arg *A = Args.getLastArg(options::OPT_fcx_fortran_rules)) - CmdArgs.push_back("-fcx-fortran-rules"); - if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_limited_range)) - CmdArgs.push_back("-fno-cx-limited-range"); - if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_fortran_rules)) - CmdArgs.push_back("-fno-cx-fortran-rules"); + if (const Arg *A = Args.getLastArg(options::OPT_fcx_fortran_rules)) + CmdArgs.push_back("-fcx-fortran-rules"); + if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_limited_range)) + CmdArgs.push_back("-fno-cx-limited-range"); + if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_fortran_rules)) + CmdArgs.push_back("-fno-cx-fortran-rules"); } static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs, >From 0441590540241bf5b4fe6a26a79870ca30ae4246 Mon Sep 17 00:00:00 2001 From: Ammarguellat <zahira.ammarguel...@intel.com> Date: Thu, 26 Oct 2023 06:28:43 -0700 Subject: [PATCH 11/11] Fix format and error (pragma_unknow.c). --- clang/include/clang/Basic/DiagnosticParseKinds.td | 2 +- clang/lib/Lex/Pragma.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index d6652e6a610c1be..902fbf4a0d692c0 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1349,7 +1349,7 @@ def warn_omp_extra_tokens_at_eol : Warning< "extra tokens at the end of '#pragma omp %0' are ignored">, InGroup<ExtraTokens>; def err_omp_multiple_step_or_linear_modifier : Error< - "multiple %select{'step size'|'linear modifier'}0 found in linear clause">; + "multiple %select{'step size'|'linear modifier'}0 found in linear clause">; def warn_pragma_expected_colon_r_paren : Warning< "missing ':' or ')' after %0 - ignoring">, InGroup<IgnoredPragmas>; def err_omp_unknown_directive : Error< diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index 35ab42cb6b5ef85..a01959077b8fa56 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -987,8 +987,10 @@ bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) { // Verify that this is followed by EOD. LexUnexpandedToken(Tok); - if (Tok.isNot(tok::eod)) + if (Tok.isNot(tok::eod)) { Diag(Tok, diag::ext_pragma_syntax_eod); + DiscardUntilEndOfDirective(); + } return false; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits