Fix C++23 build errors Imports the PRs in [1] + manual fixes in [2] (we need to replace insert with push_back because some iterator class doesn't satisfy forward iterator constraints). [1] https://github.com/llvm/llvm-project/commit/687bd77e2c26487cba727aacfa7067dd01286be0 https://github.com/llvm/llvm-project/commit/76bc1eddb2cf8b6cc073649ade21b59bbed438a2 https://github.com/llvm/llvm-project/commit/44ff94e99e0380d520d7e9803100044867ab08db [2] https://source.chromium.org/chromium/chromium/src/+/main:third_party/swiftshader/third_party/llvm-10.0/llvm/include/llvm/Analysis/LoopInfoImpl.h;l=443;drc=404b52be2561a3e090569ea66076c9615481ecc6 https://source.chromium.org/chromium/chromium/src/+/main:third_party/swiftshader/third_party/llvm-10.0/llvm/lib/Analysis/LazyValueInfo.cpp;l=348;drc=404b52be2561a3e090569ea66076c9615481ecc6 Bug: 388068055 Change-Id: I5c60ac69594a2520491ee64993bad424476fe389 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/76548 Reviewed-by: Corentin Wallez <cwallez@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Commit-Queue: Corentin Wallez <cwallez@google.com> Tested-by: Corentin Wallez <cwallez@google.com>
diff --git a/third_party/llvm-10.0/llvm/include/llvm/ADT/APFloat.h b/third_party/llvm-10.0/llvm/include/llvm/ADT/APFloat.h index ed25b2c..28c1a95 100644 --- a/third_party/llvm-10.0/llvm/include/llvm/ADT/APFloat.h +++ b/third_party/llvm-10.0/llvm/include/llvm/ADT/APFloat.h
@@ -609,21 +609,14 @@ DoubleAPFloat(DoubleAPFloat &&RHS); DoubleAPFloat &operator=(const DoubleAPFloat &RHS); - - DoubleAPFloat &operator=(DoubleAPFloat &&RHS) { - if (this != &RHS) { - this->~DoubleAPFloat(); - new (this) DoubleAPFloat(std::move(RHS)); - } - return *this; - } + inline DoubleAPFloat &operator=(DoubleAPFloat &&RHS); bool needsCleanup() const { return Floats != nullptr; } - APFloat &getFirst() { return Floats[0]; } - const APFloat &getFirst() const { return Floats[0]; } - APFloat &getSecond() { return Floats[1]; } - const APFloat &getSecond() const { return Floats[1]; } + inline APFloat &getFirst(); + inline const APFloat &getFirst() const; + inline APFloat &getSecond(); + inline const APFloat &getSecond() const; opStatus add(const DoubleAPFloat &RHS, roundingMode RM); opStatus subtract(const DoubleAPFloat &RHS, roundingMode RM); @@ -1263,6 +1256,27 @@ return (A.compare(B) == APFloat::cmpLessThan) ? B : A; } +// We want the following functions to be available in the header for inlining. +// We cannot define them inline in the class definition of `DoubleAPFloat` +// because doing so would instantiate `std::unique_ptr<APFloat[]>` before +// `APFloat` is defined, and that would be undefined behavior. +namespace detail { + +DoubleAPFloat &DoubleAPFloat::operator=(DoubleAPFloat &&RHS) { + if (this != &RHS) { + this->~DoubleAPFloat(); + new (this) DoubleAPFloat(std::move(RHS)); + } + return *this; +} + +APFloat &DoubleAPFloat::getFirst() { return Floats[0]; } +const APFloat &DoubleAPFloat::getFirst() const { return Floats[0]; } +APFloat &DoubleAPFloat::getSecond() { return Floats[1]; } +const APFloat &DoubleAPFloat::getSecond() const { return Floats[1]; } + +} // namespace detail + /// Implements IEEE 754-2018 minimum semantics. Returns the smaller of 2 /// arguments, propagating NaNs and treating -0 as less than +0. LLVM_READONLY
diff --git a/third_party/llvm-10.0/llvm/include/llvm/Analysis/AliasAnalysis.h b/third_party/llvm-10.0/llvm/include/llvm/Analysis/AliasAnalysis.h index 0bf979a..756d493 100644 --- a/third_party/llvm-10.0/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/third_party/llvm-10.0/llvm/include/llvm/Analysis/AliasAnalysis.h
@@ -313,7 +313,7 @@ public: // Make these results default constructable and movable. We have to spell // these out because MSVC won't synthesize them. - AAResults(const TargetLibraryInfo &TLI) : TLI(TLI) {} + AAResults(const TargetLibraryInfo &TLI); AAResults(AAResults &&Arg); ~AAResults();
diff --git a/third_party/llvm-10.0/llvm/include/llvm/Analysis/LoopInfoImpl.h b/third_party/llvm-10.0/llvm/include/llvm/Analysis/LoopInfoImpl.h index 99f192a..3bcb7d0 100644 --- a/third_party/llvm-10.0/llvm/include/llvm/Analysis/LoopInfoImpl.h +++ b/third_party/llvm-10.0/llvm/include/llvm/Analysis/LoopInfoImpl.h
@@ -440,9 +440,9 @@ if (PredBB == L->getHeader()) continue; // Push all block predecessors on the worklist. - ReverseCFGWorklist.insert(ReverseCFGWorklist.end(), - InvBlockTraits::child_begin(PredBB), - InvBlockTraits::child_end(PredBB)); + for (auto it = InvBlockTraits::child_begin(PredBB); it != InvBlockTraits::child_end(PredBB); it++) { + ReverseCFGWorklist.push_back(*it); + } } else { // This is a discovered block. Find its outermost discovered loop. while (LoopT *Parent = Subloop->getParentLoop())
diff --git a/third_party/llvm-10.0/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/third_party/llvm-10.0/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h index 7b84044..c15487a 100644 --- a/third_party/llvm-10.0/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h +++ b/third_party/llvm-10.0/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -68,6 +68,9 @@ /// Output the remark via the diagnostic handler and to the /// optimization record file. void emit(DiagnosticInfoOptimizationBase &OptDiag); + /// Also allow r-value for OptDiag to allow emitting a temporarily-constructed + /// diagnostic. + void emit(DiagnosticInfoOptimizationBase &&OptDiag) { emit(OptDiag); } /// Take a lambda that returns a remark which will be emitted. Second /// argument is only used to restrict this to functions.
diff --git a/third_party/llvm-10.0/llvm/include/llvm/IR/DiagnosticInfo.h b/third_party/llvm-10.0/llvm/include/llvm/IR/DiagnosticInfo.h index ec46998..206e0e1 100644 --- a/third_party/llvm-10.0/llvm/include/llvm/IR/DiagnosticInfo.h +++ b/third_party/llvm-10.0/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -27,6 +27,7 @@ #include <functional> #include <iterator> #include <string> +#include <utility> namespace llvm { @@ -388,7 +389,7 @@ /// Return the absolute path tot the file. std::string getAbsolutePath() const; - + const Function &getFunction() const { return Fn; } DiagnosticLocation getLocation() const { return Loc; } @@ -529,75 +530,47 @@ /// common base class. This allows returning the result of the insertion /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah". template <class RemarkT> -RemarkT & -operator<<(RemarkT &R, - typename std::enable_if< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - StringRef>::type S) { +decltype(auto) +operator<<(RemarkT &&R, + std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase, + std::remove_reference_t<RemarkT>>, + StringRef> + S) { R.insert(S); - return R; + return std::forward<RemarkT>(R); } -/// Also allow r-value for the remark to allow insertion into a -/// temporarily-constructed remark. template <class RemarkT> -RemarkT & +decltype(auto) operator<<(RemarkT &&R, - typename std::enable_if< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - StringRef>::type S) { - R.insert(S); - return R; -} - -template <class RemarkT> -RemarkT & -operator<<(RemarkT &R, - typename std::enable_if< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - DiagnosticInfoOptimizationBase::Argument>::type A) { + std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase, + std::remove_reference_t<RemarkT>>, + DiagnosticInfoOptimizationBase::Argument> + A) { R.insert(A); - return R; + return std::forward<RemarkT>(R); } template <class RemarkT> -RemarkT & +decltype(auto) operator<<(RemarkT &&R, - typename std::enable_if< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - DiagnosticInfoOptimizationBase::Argument>::type A) { - R.insert(A); - return R; -} - -template <class RemarkT> -RemarkT & -operator<<(RemarkT &R, - typename std::enable_if< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - DiagnosticInfoOptimizationBase::setIsVerbose>::type V) { + std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase, + std::remove_reference_t<RemarkT>>, + DiagnosticInfoOptimizationBase::setIsVerbose> + V) { R.insert(V); - return R; + return std::forward<RemarkT>(R); } template <class RemarkT> -RemarkT & +decltype(auto) operator<<(RemarkT &&R, - typename std::enable_if< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - DiagnosticInfoOptimizationBase::setIsVerbose>::type V) { - R.insert(V); - return R; -} - -template <class RemarkT> -RemarkT & -operator<<(RemarkT &R, - typename std::enable_if< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - DiagnosticInfoOptimizationBase::setExtraArgs>::type EA) { + std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase, + std::remove_reference_t<RemarkT>>, + DiagnosticInfoOptimizationBase::setExtraArgs> + EA) { R.insert(EA); - return R; + return std::forward<RemarkT>(R); } /// Common features for diagnostics dealing with optimization remarks
diff --git a/third_party/llvm-10.0/llvm/include/llvm/IR/ModuleSummaryIndex.h b/third_party/llvm-10.0/llvm/include/llvm/IR/ModuleSummaryIndex.h index aa4054c..97119ee 100644 --- a/third_party/llvm-10.0/llvm/include/llvm/IR/ModuleSummaryIndex.h +++ b/third_party/llvm-10.0/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -143,7 +143,7 @@ StringRef Name; } U; - GlobalValueSummaryInfo(bool HaveGVs) : U(HaveGVs) {} + inline GlobalValueSummaryInfo(bool HaveGVs); /// List of global value summary structures for a particular value held /// in the GlobalValueMap. Requires a vector in the case of multiple @@ -423,6 +423,8 @@ friend class ModuleSummaryIndex; }; +GlobalValueSummaryInfo::GlobalValueSummaryInfo(bool HaveGVs) : U(HaveGVs) {} + /// Alias summary information. class AliasSummary : public GlobalValueSummary { ValueInfo AliaseeValueInfo;
diff --git a/third_party/llvm-10.0/llvm/lib/Analysis/AliasAnalysis.cpp b/third_party/llvm-10.0/llvm/lib/Analysis/AliasAnalysis.cpp index 1c7678a..3c9aef9 100644 --- a/third_party/llvm-10.0/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/third_party/llvm-10.0/llvm/lib/Analysis/AliasAnalysis.cpp
@@ -61,6 +61,8 @@ static cl::opt<bool> DisableBasicAA("disable-basicaa", cl::Hidden, cl::init(false)); +AAResults::AAResults(const TargetLibraryInfo &TLI) : TLI(TLI) {} + AAResults::AAResults(AAResults &&Arg) : TLI(Arg.TLI), AAs(std::move(Arg.AAs)), AADeps(std::move(Arg.AADeps)) { for (auto &AA : AAs)
diff --git a/third_party/llvm-10.0/llvm/lib/Analysis/LazyValueInfo.cpp b/third_party/llvm-10.0/llvm/lib/Analysis/LazyValueInfo.cpp index bad2de9..3581842 100644 --- a/third_party/llvm-10.0/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/third_party/llvm-10.0/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -345,7 +345,9 @@ if (!changed) continue; - worklist.insert(worklist.end(), succ_begin(ToUpdate), succ_end(ToUpdate)); + for (auto it = succ_begin(ToUpdate); it != succ_end(ToUpdate); it++) { + worklist.push_back(*it); + } } }
diff --git a/third_party/llvm-10.0/llvm/lib/Transforms/IPO/Inliner.cpp b/third_party/llvm-10.0/llvm/lib/Transforms/IPO/Inliner.cpp index 4b72261..97c6835 100644 --- a/third_party/llvm-10.0/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/third_party/llvm-10.0/llvm/lib/Transforms/IPO/Inliner.cpp
@@ -391,7 +391,7 @@ } template <class RemarkT> -RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) { +decltype(auto) operator<<(RemarkT &&R, const InlineCost &IC) { using namespace ore; if (IC.isAlways()) { R << "(cost=always)"; @@ -403,7 +403,7 @@ } if (const char *Reason = IC.getReason()) R << ": " << ore::NV("Reason", Reason); - return R; + return std::forward<RemarkT>(R);; } static std::string inlineCostStr(const InlineCost &IC) {
diff --git a/third_party/llvm-16.0/llvm/include/llvm/ADT/APFloat.h b/third_party/llvm-16.0/llvm/include/llvm/ADT/APFloat.h index c0e2d13..3f85a51 100644 --- a/third_party/llvm-16.0/llvm/include/llvm/ADT/APFloat.h +++ b/third_party/llvm-16.0/llvm/include/llvm/ADT/APFloat.h
@@ -641,20 +641,14 @@ DoubleAPFloat &operator=(const DoubleAPFloat &RHS); - DoubleAPFloat &operator=(DoubleAPFloat &&RHS) { - if (this != &RHS) { - this->~DoubleAPFloat(); - new (this) DoubleAPFloat(std::move(RHS)); - } - return *this; - } + inline DoubleAPFloat &operator=(DoubleAPFloat &&RHS); bool needsCleanup() const { return Floats != nullptr; } - APFloat &getFirst() { return Floats[0]; } - const APFloat &getFirst() const { return Floats[0]; } - APFloat &getSecond() { return Floats[1]; } - const APFloat &getSecond() const { return Floats[1]; } + inline APFloat &getFirst(); + inline const APFloat &getFirst(); + inline APFloat &getSecond(); + inline const APFloat &getSecond(); opStatus add(const DoubleAPFloat &RHS, roundingMode RM); opStatus subtract(const DoubleAPFloat &RHS, roundingMode RM); @@ -1332,6 +1326,27 @@ return A < B ? B : A; } +// We want the following functions to be available in the header for inlining. +// We cannot define them inline in the class definition of `DoubleAPFloat` +// because doing so would instantiate `std::unique_ptr<APFloat[]>` before +// `APFloat` is defined, and that would be undefined behavior. +namespace detail { + +DoubleAPFloat &DoubleAPFloat::operator=(DoubleAPFloat &&RHS) { + if (this != &RHS) { + this->~DoubleAPFloat(); + new (this) DoubleAPFloat(std::move(RHS)); + } + return *this; +} + +APFloat &DoubleAPFloat::getFirst() { return Floats[0]; } +const APFloat &DoubleAPFloat::getFirst() const { return Floats[0]; } +APFloat &DoubleAPFloat::getSecond() { return Floats[1]; } +const APFloat &DoubleAPFloat::getSecond() const { return Floats[1]; } + +} // namespace detail + /// Implements IEEE 754-2018 minimum semantics. Returns the smaller of 2 /// arguments, propagating NaNs and treating -0 as less than +0. LLVM_READONLY
diff --git a/third_party/llvm-16.0/llvm/include/llvm/Analysis/AliasAnalysis.h b/third_party/llvm-16.0/llvm/include/llvm/Analysis/AliasAnalysis.h index 953e15e..5ae0b90 100644 --- a/third_party/llvm-16.0/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/third_party/llvm-16.0/llvm/include/llvm/Analysis/AliasAnalysis.h
@@ -295,7 +295,7 @@ public: // Make these results default constructable and movable. We have to spell // these out because MSVC won't synthesize them. - AAResults(const TargetLibraryInfo &TLI) : TLI(TLI) {} + AAResults(const TargetLibraryInfo &TLI); AAResults(AAResults &&Arg); ~AAResults();
diff --git a/third_party/llvm-16.0/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/third_party/llvm-16.0/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h index 8aaeaf2..0ec58d1 100644 --- a/third_party/llvm-16.0/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h +++ b/third_party/llvm-16.0/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -70,6 +70,9 @@ /// Output the remark via the diagnostic handler and to the /// optimization record file. void emit(DiagnosticInfoOptimizationBase &OptDiag); + /// Also allow r-value for OptDiag to allow emitting a temporarily-constructed + /// diagnostic. + void emit(DiagnosticInfoOptimizationBase &&OptDiag) { emit(OptDiag); } /// Take a lambda that returns a remark which will be emitted. Second /// argument is only used to restrict this to functions.
diff --git a/third_party/llvm-16.0/llvm/include/llvm/IR/DiagnosticInfo.h b/third_party/llvm-16.0/llvm/include/llvm/IR/DiagnosticInfo.h index 628445f..1983fba 100644 --- a/third_party/llvm-16.0/llvm/include/llvm/IR/DiagnosticInfo.h +++ b/third_party/llvm-16.0/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -30,6 +30,7 @@ #include <iterator> #include <optional> #include <string> +#include <utility> namespace llvm { @@ -539,82 +540,47 @@ /// common base class. This allows returning the result of the insertion /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah". template <class RemarkT> -RemarkT & -operator<<(RemarkT &R, - std::enable_if_t< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - StringRef> +decltype(auto) +operator<<(RemarkT &&R, + std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase, + std::remove_reference_t<RemarkT>>, + StringRef> S) { R.insert(S); - return R; + return std::forward<RemarkT>(R); } -/// Also allow r-value for the remark to allow insertion into a -/// temporarily-constructed remark. template <class RemarkT> -RemarkT & +decltype(auto) operator<<(RemarkT &&R, - std::enable_if_t< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - StringRef> - S) { - R.insert(S); - return R; -} - -template <class RemarkT> -RemarkT & -operator<<(RemarkT &R, - std::enable_if_t< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - DiagnosticInfoOptimizationBase::Argument> + std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase, + std::remove_reference_t<RemarkT>>, + DiagnosticInfoOptimizationBase::Argument> A) { R.insert(A); - return R; + return std::forward<RemarkT>(R); } template <class RemarkT> -RemarkT & +decltype(auto) operator<<(RemarkT &&R, - std::enable_if_t< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - DiagnosticInfoOptimizationBase::Argument> - A) { - R.insert(A); - return R; -} - -template <class RemarkT> -RemarkT & -operator<<(RemarkT &R, - std::enable_if_t< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - DiagnosticInfoOptimizationBase::setIsVerbose> + std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase, + std::remove_reference_t<RemarkT>>, + DiagnosticInfoOptimizationBase::setIsVerbose> V) { R.insert(V); - return R; + return std::forward<RemarkT>(R); } template <class RemarkT> -RemarkT & +decltype(auto) operator<<(RemarkT &&R, - std::enable_if_t< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - DiagnosticInfoOptimizationBase::setIsVerbose> - V) { - R.insert(V); - return R; -} - -template <class RemarkT> -RemarkT & -operator<<(RemarkT &R, - std::enable_if_t< - std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, - DiagnosticInfoOptimizationBase::setExtraArgs> + std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase, + std::remove_reference_t<RemarkT>>, + DiagnosticInfoOptimizationBase::setExtraArgs> EA) { R.insert(EA); - return R; + return std::forward<RemarkT>(R); } /// Common features for diagnostics dealing with optimization remarks
diff --git a/third_party/llvm-16.0/llvm/include/llvm/IR/ModuleSummaryIndex.h b/third_party/llvm-16.0/llvm/include/llvm/IR/ModuleSummaryIndex.h index e523652..4e249b1 100644 --- a/third_party/llvm-16.0/llvm/include/llvm/IR/ModuleSummaryIndex.h +++ b/third_party/llvm-16.0/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -147,7 +147,7 @@ StringRef Name; } U; - GlobalValueSummaryInfo(bool HaveGVs) : U(HaveGVs) {} + inline GlobalValueSummaryInfo(bool HaveGVs); /// List of global value summary structures for a particular value held /// in the GlobalValueMap. Requires a vector in the case of multiple @@ -519,6 +519,8 @@ friend class ModuleSummaryIndex; }; +GlobalValueSummaryInfo::GlobalValueSummaryInfo(bool HaveGVs) : U(HaveGVs) {} + /// Alias summary information. class AliasSummary : public GlobalValueSummary { ValueInfo AliaseeValueInfo;
diff --git a/third_party/llvm-16.0/llvm/lib/Analysis/AliasAnalysis.cpp b/third_party/llvm-16.0/llvm/lib/Analysis/AliasAnalysis.cpp index 9e24f6b..743ce95 100644 --- a/third_party/llvm-16.0/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/third_party/llvm-16.0/llvm/lib/Analysis/AliasAnalysis.cpp
@@ -73,6 +73,8 @@ static const bool EnableAATrace = false; #endif +AAResults::AAResults(const TargetLibraryInfo &TLI) : TLI(TLI) {} + AAResults::AAResults(AAResults &&Arg) : TLI(Arg.TLI), AAs(std::move(Arg.AAs)), AADeps(std::move(Arg.AADeps)) {}
diff --git a/third_party/llvm-16.0/llvm/lib/Analysis/InlineAdvisor.cpp b/third_party/llvm-16.0/llvm/lib/Analysis/InlineAdvisor.cpp index 540aad7..33961b2 100644 --- a/third_party/llvm-16.0/llvm/lib/Analysis/InlineAdvisor.cpp +++ b/third_party/llvm-16.0/llvm/lib/Analysis/InlineAdvisor.cpp
@@ -338,7 +338,7 @@ } template <class RemarkT> -RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) { +decltype(auto) operator<<(RemarkT &&R, const InlineCost &IC) { using namespace ore; if (IC.isAlways()) { R << "(cost=always)"; @@ -350,7 +350,7 @@ } if (const char *Reason = IC.getReason()) R << ": " << ore::NV("Reason", Reason); - return R; + return std::forward<RemarkT>(R); } } // namespace llvm