mibintc created this revision.
mibintc added reviewers: rjmccall, sepavloff, andrew.w.kaylor.
Herald added a project: clang.
mibintc marked an inline comment as done.
mibintc added a comment.

added an inline comment



================
Comment at: clang/include/clang/AST/Stmt.h:618
     // Only meaningful for floating point types.
-    unsigned FPFeatures : 8;
+    unsigned FPFeatures : 14;
   };
----------------
This correction belongs in the parent revision, i will move it there.


The folks at Intel who program FPGA would like to be able to control the 
FastMathFlag that governs reassociating operations at the source level using 
pragma's e.g.
#pragma clang fp reassoc(on) // allow reassociation of operations

This patch builds on reviews.llvm.org/D72841 <https://reviews.llvm.org/D72841>

I just realized that I need to update the user manual to describe the syntax, 
so I owe you an update.  Hoping you will take a look


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D78827

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/CodeGen/fp-reassoc-pragma-fails.cpp
  clang/test/CodeGen/fp-reassoc-pragma.cpp

Index: clang/test/CodeGen/fp-reassoc-pragma.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/fp-reassoc-pragma.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+// Simple case
+float fp_reassoc_simple(float a, float b, float c) {
+// CHECK: _Z17fp_reassoc_simplefff
+// CHECK: %[[M:.+]] = fmul reassoc float %a, %b
+// CHECK-NEXT: fadd reassoc float %[[M]], %c
+#pragma clang fp reassoc(on)
+  return a * b + c;
+}
+
+// Reassoc pragma should only apply to its scope
+float fp_reassoc_scoped(float a, float b, float c) {
+  // CHECK: _Z17fp_reassoc_scopedfff
+  // CHECK: %[[M:.+]] = fmul float %a, %b
+  // CHECK-NEXT: fadd float %[[M]], %c
+  {
+#pragma clang fp reassoc(on)
+  }
+  return a * b + c;
+}
+
+// Reassoc pragma should apply to templates as well
+class Foo {};
+Foo operator+(Foo, Foo);
+template <typename T>
+T template_reassoc(T a, T b, T c) {
+#pragma clang fp reassoc(on)
+  return ((a + b) - c) + c;
+}
+
+float fp_reassoc_template(float a, float b, float c) {
+  // CHECK: _Z19fp_reassoc_templatefff
+  // CHECK: %[[A1:.+]] = fadd reassoc float %a, %b
+  // CHECK-NEXT: %[[A2:.+]] = fsub reassoc float %[[A1]], %c
+  // CHECK-NEXT: fadd reassoc float %[[A2]], %c
+  return template_reassoc<float>(a, b, c);
+}
+
+// File Scoping should work across functions
+#pragma clang fp reassoc(on)
+float fp_file_scope_on(float a, float b, float c) {
+  // CHECK: _Z16fp_file_scope_onfff
+  // CHECK: %[[M1:.+]] = fmul reassoc float %a, %c
+  // CHECK-NEXT: %[[M2:.+]] = fmul reassoc float %b, %c
+  // CHECK-NEXT: fadd reassoc float %[[M1]], %[[M2]]
+  return (a * c) + (b * c);
+}
+
+// Inner pragma has precedence
+float fp_file_scope_stop(float a, float b, float c) {
+  // CHECK: _Z18fp_file_scope_stopfff
+  // CHECK: %[[A:.+]] = fadd reassoc float %a, %a
+  // CHECK: %[[M1:.+]] = fmul float %[[A]], %c
+  // CHECK-NEXT: %[[M2:.+]] = fmul float %b, %c
+  // CHECK-NEXT: fsub float %[[M1]], %[[M2]]
+  a = a + a;
+  {
+#pragma clang fp reassoc(off)
+    return (a * c) - (b * c);
+  }
+}
+
+#pragma clang fp reassoc(off)
+float fp_reassoc_off(float a, float b, float c) {
+  // CHECK: _Z14fp_reassoc_offfff
+  // CHECK: %[[D1:.+]] = fdiv float %a, %c
+  // CHECK-NEXT: %[[D2:.+]] = fdiv float %b, %c
+  // CHECK-NEXT: fadd float %[[D1]], %[[D2]]
+  return (a / c) + (b / c);
+}
+
+// Takes latest flag
+float fp_reassoc_many(float a, float b, float c) {
+// CHECK: _Z15fp_reassoc_manyfff
+// CHECK: %[[D1:.+]] = fdiv reassoc float %a, %c
+// CHECK-NEXT: %[[D2:.+]] = fdiv reassoc float %b, %c
+// CHECK-NEXT: fadd reassoc float %[[D1]], %[[D2]]
+#pragma clang fp reassoc(off) reassoc(on)
+  return (a / c) + (b / c);
+}
+
+// Pragma does not propagate through called functions
+float helper_func(float a, float b, float c) { return a + b + c; }
+float fp_reassoc_call_helper(float a, float b, float c) {
+// CHECK: _Z22fp_reassoc_call_helperfff
+// CHECK: %[[S1:.+]] = fadd float %a, %b
+// CHECK-NEXT: fadd float %[[S1]], %c
+#pragma clang fp reassoc(on)
+  return helper_func(a, b, c);
+}
Index: clang/test/CodeGen/fp-reassoc-pragma-fails.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/fp-reassoc-pragma-fails.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+float fp_reassoc_fail(float a, float b) {
+  // CHECK-LABEL: fp_reassoc_fail
+  // expected-error@+2{{'#pragma clang fp' can only appear at file scope or at the start of a compound statement}}
+  float c = a + b;
+#pragma clang fp reassoc(on)
+  return c - b;
+}
+
+float fp_reassoc_no_fast(float a, float b) {
+// CHECK-LABEL: fp_reassoc_no_fast
+// expected-error@+1{{unexpected argument 'fast' to '#pragma clang fp reassoc'; expected 'on' or 'off'}}
+#pragma clang fp reassoc(fast)
+  return a - b;
+}
Index: clang/lib/Sema/SemaAttr.cpp
===================================================================
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -988,20 +988,33 @@
   }
 }
 
-void Sema::ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC) {
+void Sema::ActOnPragmaFPContract(LangOptions::FPModeKind FPC) {
   switch (FPC) {
-  case LangOptions::FPC_On:
+  case LangOptions::FPM_On:
     CurFPFeatures.setAllowFPContractWithinStatement();
     break;
-  case LangOptions::FPC_Fast:
+  case LangOptions::FPM_Fast:
     CurFPFeatures.setAllowFPContractAcrossStatement();
     break;
-  case LangOptions::FPC_Off:
+  case LangOptions::FPM_Off:
     CurFPFeatures.setDisallowFPContract();
     break;
   }
 }
 
+void Sema::ActOnPragmaFPReassoc(LangOptions::FPModeKind FPC) {
+  switch (FPC) {
+  default:
+    llvm_unreachable("invalid pragma fp reassoc kind");
+  case LangOptions::FPM_On:
+    CurFPFeatures.setAllowAssociativeMath(true);
+    break;
+  case LangOptions::FPM_Off:
+    CurFPFeatures.setAllowAssociativeMath(false);
+    break;
+  }
+}
+
 void Sema::setRoundingMode(llvm::RoundingMode FPR) {
   CurFPFeatures.setRoundingMode(FPR);
 }
@@ -1011,9 +1024,11 @@
 }
 
 void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc,
-                                 LangOptions::FEnvAccessModeKind FPC) {
+                                 LangOptions::FPModeKind FPC) {
   switch (FPC) {
-  case LangOptions::FEA_On:
+  default:
+    llvm_unreachable("invalid pragma fp fenv access kind");
+  case LangOptions::FPM_On:
     // Verify Microsoft restriction:
     // You can't enable fenv_access unless precise semantics are enabled.
     // Precise semantics can be enabled either by the float_control
@@ -1022,7 +1037,7 @@
       Diag(Loc, diag::err_pragma_fenv_requires_precise);
     CurFPFeatures.setAllowFEnvAccess();
     break;
-  case LangOptions::FEA_Off:
+  case LangOptions::FPM_Off:
     CurFPFeatures.setDisallowFEnvAccess();
     break;
   }
Index: clang/lib/Parse/ParsePragma.cpp
===================================================================
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -643,13 +643,13 @@
     static_cast<tok::OnOffSwitch>(
     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
 
-  LangOptions::FPContractModeKind FPC;
+  LangOptions::FPModeKind FPC;
   switch (OOS) {
   case tok::OOS_ON:
-    FPC = LangOptions::FPC_On;
+    FPC = LangOptions::FPM_On;
     break;
   case tok::OOS_OFF:
-    FPC = LangOptions::FPC_Off;
+    FPC = LangOptions::FPM_Off;
     break;
   case tok::OOS_DEFAULT:
     FPC = getLangOpts().getDefaultFPContractMode();
@@ -677,16 +677,16 @@
     static_cast<tok::OnOffSwitch>(
     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
 
-  LangOptions::FEnvAccessModeKind FPC;
+  LangOptions::FPModeKind FPC;
   switch (OOS) {
   case tok::OOS_ON:
-    FPC = LangOptions::FEA_On;
+    FPC = LangOptions::FPM_On;
     break;
   case tok::OOS_OFF:
-    FPC = LangOptions::FEA_Off;
+    FPC = LangOptions::FPM_Off;
     break;
   case tok::OOS_DEFAULT: // FIXME: Add this cli option when it makes sense.
-    FPC = LangOptions::FEA_Off;
+    FPC = LangOptions::FPM_Off;
     break;
   }
 
@@ -2821,7 +2821,7 @@
 namespace {
 /// Used as the annotation value for tok::annot_pragma_fp.
 struct TokFPAnnotValue {
-  enum FlagKinds { Contract };
+  enum FlagKinds { Contract, Reassoc };
   enum FlagValues { On, Off, Fast };
 
   FlagKinds FlagKind;
@@ -2849,6 +2849,7 @@
         llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
             OptionInfo->getName())
             .Case("contract", TokFPAnnotValue::Contract)
+            .Case("reassoc", TokFPAnnotValue::Reassoc)
             .Default(None);
     if (!FlagKind) {
       PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
@@ -2879,9 +2880,15 @@
             .Case("fast", TokFPAnnotValue::Fast)
             .Default(llvm::None);
 
-    if (!FlagValue) {
-      PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
-          << PP.getSpelling(Tok) << OptionInfo->getName();
+    if (FlagKind == TokFPAnnotValue::Reassoc) {
+      if (!FlagValue || FlagValue == TokFPAnnotValue::Fast) {
+        PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
+            << PP.getSpelling(Tok) << OptionInfo->getName();
+        return;
+      }
+    } else if (!FlagValue) {
+      PP.Diag(Tok.getLocation(), diag::err_pragma_fp_contract_invalid_argument)
+          << PP.getSpelling(Tok);
       return;
     }
     PP.Lex(Tok);
@@ -2895,7 +2902,7 @@
 
     auto *AnnotValue = new (PP.getPreprocessorAllocator())
         TokFPAnnotValue{*FlagKind, *FlagValue};
-    // Generate the loop hint token.
+    // Generate the pragma fp annotation token.
     Token FPTok;
     FPTok.startToken();
     FPTok.setKind(tok::annot_pragma_fp);
@@ -2923,20 +2930,23 @@
   auto *AnnotValue =
       reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue());
 
-  LangOptions::FPContractModeKind FPC;
+  LangOptions::FPModeKind FPC;
   switch (AnnotValue->FlagValue) {
   case TokFPAnnotValue::On:
-    FPC = LangOptions::FPC_On;
+    FPC = LangOptions::FPM_On;
     break;
   case TokFPAnnotValue::Fast:
-    FPC = LangOptions::FPC_Fast;
+    FPC = LangOptions::FPM_Fast;
     break;
   case TokFPAnnotValue::Off:
-    FPC = LangOptions::FPC_Off;
+    FPC = LangOptions::FPM_Off;
     break;
   }
 
-  Actions.ActOnPragmaFPContract(FPC);
+  if (AnnotValue->FlagKind == TokFPAnnotValue::Reassoc)
+    Actions.ActOnPragmaFPReassoc(FPC);
+  else
+    Actions.ActOnPragmaFPContract(FPC);
   ConsumeAnnotationToken();
 }
 
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -2318,7 +2318,7 @@
     Opts.AltiVec = 0;
     Opts.ZVector = 0;
     Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::None);
-    Opts.setDefaultFPContractMode(LangOptions::FPC_On);
+    Opts.setDefaultFPContractMode(LangOptions::FPM_On);
     Opts.NativeHalfType = 1;
     Opts.NativeHalfArgsAndReturns = 1;
     Opts.OpenCLCPlusPlus = Opts.CPlusPlus;
@@ -2338,7 +2338,7 @@
   Opts.CUDA = IK.getLanguage() == Language::CUDA || Opts.HIP;
   if (Opts.CUDA)
     // Set default FP_CONTRACT to FAST.
-    Opts.setDefaultFPContractMode(LangOptions::FPC_Fast);
+    Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
 
   Opts.RenderScript = IK.getLanguage() == Language::RenderScript;
   if (Opts.RenderScript) {
@@ -3204,11 +3204,11 @@
   if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
     StringRef Val = A->getValue();
     if (Val == "fast")
-      Opts.setDefaultFPContractMode(LangOptions::FPC_Fast);
+      Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
     else if (Val == "on")
-      Opts.setDefaultFPContractMode(LangOptions::FPC_On);
+      Opts.setDefaultFPContractMode(LangOptions::FPM_On);
     else if (Val == "off")
-      Opts.setDefaultFPContractMode(LangOptions::FPC_Off);
+      Opts.setDefaultFPContractMode(LangOptions::FPM_Off);
     else
       Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
   }
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -450,15 +450,15 @@
 
   // Set FP fusion mode.
   switch (LangOpts.getDefaultFPContractMode()) {
-  case LangOptions::FPC_Off:
+  case LangOptions::FPM_Off:
     // Preserve any contraction performed by the front-end.  (Strict performs
     // splitting of the muladd intrinsic in the backend.)
     Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
     break;
-  case LangOptions::FPC_On:
+  case LangOptions::FPM_On:
     Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
     break;
-  case LangOptions::FPC_Fast:
+  case LangOptions::FPM_Fast:
     Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
     break;
   }
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -9617,12 +9617,15 @@
   /// ActOnPragmaFPContract - Called on well formed
   /// \#pragma {STDC,OPENCL} FP_CONTRACT and
   /// \#pragma clang fp contract
-  void ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC);
+  void ActOnPragmaFPContract(LangOptions::FPModeKind FPC);
+
+  /// ActOnPragmaFPReassoc - Called on well formed
+  /// \#pragma clang fp reassoc
+  void ActOnPragmaFPReassoc(LangOptions::FPModeKind FPC);
 
   /// ActOnPragmaFenvAccess - Called on well formed
   /// \#pragma STDC FENV_ACCESS
-  void ActOnPragmaFEnvAccess(SourceLocation Loc,
-                             LangOptions::FEnvAccessModeKind FPC);
+  void ActOnPragmaFEnvAccess(SourceLocation Loc, LangOptions::FPModeKind FPC);
 
   /// Called to set rounding mode for floating point operations.
   void setRoundingMode(llvm::RoundingMode);
Index: clang/include/clang/Basic/LangOptions.h
===================================================================
--- clang/include/clang/Basic/LangOptions.h
+++ clang/include/clang/Basic/LangOptions.h
@@ -174,22 +174,15 @@
     Swift4_1,
   };
 
-  enum FPContractModeKind {
-    // Form fused FP ops only where result will not be affected.
-    FPC_Off,
+  enum FPModeKind {
+    // Disable the floating point pragma
+    FPM_Off,
 
-    // Form fused FP ops according to FP_CONTRACT rules.
-    FPC_On,
+    // Enable the floating point pragma
+    FPM_On,
 
-    // Aggressively fuse FP ops (E.g. FMA).
-    FPC_Fast
-  };
-
-  // TODO: merge FEnvAccessModeKind and FPContractModeKind
-  enum FEnvAccessModeKind {
-    FEA_Off,
-
-    FEA_On
+    // (Only for fp contract) Aggressively fuse FP ops (E.g. FMA).
+    FPM_Fast
   };
 
   /// Alias for RoundingMode::NearestTiesToEven.
@@ -380,7 +373,7 @@
 
 public:
   FPOptions()
-      : fp_contract(LangOptions::FPC_Off), fenv_access(LangOptions::FEA_Off),
+      : fp_contract(LangOptions::FPM_Off), fenv_access(LangOptions::FPM_Off),
         rounding(LangOptions::FPR_ToNearest),
         exceptions(LangOptions::FPE_Ignore), allow_reassoc(0), no_nans(0),
         no_infs(0), no_signed_zeros(0), allow_reciprocal(0), approx_func(0) {}
@@ -395,7 +388,7 @@
 
   explicit FPOptions(const LangOptions &LangOpts)
       : fp_contract(LangOpts.getDefaultFPContractMode()),
-        fenv_access(LangOptions::FEA_Off),
+        fenv_access(LangOptions::FPM_Off),
         rounding(static_cast<unsigned>(LangOpts.getFPRoundingMode())),
         exceptions(LangOpts.getFPExceptionMode()),
         allow_reassoc(LangOpts.FastMath || LangOpts.AllowFPReassoc),
@@ -420,30 +413,26 @@
   bool requiresTrailingStorage(const LangOptions &LO);
 
   bool allowFPContractWithinStatement() const {
-    return fp_contract == LangOptions::FPC_On;
+    return fp_contract == LangOptions::FPM_On;
   }
 
   bool allowFPContractAcrossStatement() const {
-    return fp_contract == LangOptions::FPC_Fast;
+    return fp_contract == LangOptions::FPM_Fast;
   }
 
   void setAllowFPContractWithinStatement() {
-    fp_contract = LangOptions::FPC_On;
+    fp_contract = LangOptions::FPM_On;
   }
 
   void setAllowFPContractAcrossStatement() {
-    fp_contract = LangOptions::FPC_Fast;
+    fp_contract = LangOptions::FPM_Fast;
   }
 
-  void setDisallowFPContract() { fp_contract = LangOptions::FPC_Off; }
+  void setDisallowFPContract() { fp_contract = LangOptions::FPM_Off; }
 
-  bool allowFEnvAccess() const {
-    return fenv_access == LangOptions::FEA_On;
-  }
+  bool allowFEnvAccess() const { return fenv_access == LangOptions::FPM_On; }
 
-  void setAllowFEnvAccess() {
-    fenv_access = LangOptions::FEA_On;
-  }
+  void setAllowFEnvAccess() { fenv_access = LangOptions::FPM_On; }
 
   void setFPPreciseEnabled(bool Value) {
     if (Value) {
@@ -457,7 +446,7 @@
     }
   }
 
-  void setDisallowFEnvAccess() { fenv_access = LangOptions::FEA_Off; }
+  void setDisallowFEnvAccess() { fenv_access = LangOptions::FPM_Off; }
 
   RoundingMode getRoundingMode() const {
     return static_cast<RoundingMode>(rounding);
@@ -507,8 +496,8 @@
 
   /// Used with getAsOpaqueInt() to manage the float_control pragma stack.
   void getFromOpaqueInt(unsigned I) {
-    fp_contract = (static_cast<LangOptions::FPContractModeKind>(I & 3));
-    fenv_access = (static_cast<LangOptions::FEnvAccessModeKind>((I >> 2) & 1));
+    fp_contract = (static_cast<LangOptions::FPModeKind>(I & 3));
+    fenv_access = (static_cast<LangOptions::FPModeKind>((I >> 2) & 1));
     rounding = static_cast<unsigned>(static_cast<RoundingMode>((I >> 3) & 7));
     exceptions = (static_cast<LangOptions::FPExceptionModeKind>((I >> 6) & 3));
     allow_reassoc = ((I >> 8) & 1);
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -268,7 +268,7 @@
 LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
 LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
 /// FP_CONTRACT mode (on/off/fast).
-ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP contraction type")
+ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type")
 ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, "FP Rounding Mode type")
 ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
 LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1332,10 +1332,13 @@
   "pipeline, pipeline_initiation_interval, vectorize_predicate, or distribute">;
 
 def err_pragma_fp_invalid_option : Error<
-  "%select{invalid|missing}0 option%select{ %1|}0; expected contract">;
+  "%select{invalid|missing}0 option%select{ %1|}0; expected contract or reassoc">;
+def err_pragma_fp_contract_invalid_argument : Error<
+  "unexpected argument '%0' to '#pragma clang fp contract'; "
+  "expected 'on', 'fast' or 'off'">;
 def err_pragma_fp_invalid_argument : Error<
   "unexpected argument '%0' to '#pragma clang fp %1'; "
-  "expected 'on', 'fast' or 'off'">;
+  "expected 'on' or 'off'">;
 
 def err_pragma_invalid_keyword : Error<
   "invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">;
Index: clang/include/clang/AST/Stmt.h
===================================================================
--- clang/include/clang/AST/Stmt.h
+++ clang/include/clang/AST/Stmt.h
@@ -615,7 +615,7 @@
     unsigned OperatorKind : 6;
 
     // Only meaningful for floating point types.
-    unsigned FPFeatures : 8;
+    unsigned FPFeatures : 14;
   };
 
   class CXXRewrittenBinaryOperatorBitfields {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to