From 0863125cfca574760d351caaf2a12982993d50f0 Mon Sep 17 00:00:00 2001 From: "petro.zarytskyi" Date: Thu, 30 Nov 2023 23:17:22 +0200 Subject: [PATCH] Introduce To-Be-Recorded Analysis in Clad. This patch request optimizes storing and restoring in the reverse mode of Clad and introduces TBR analysis to determine when variables should be stored. Fixes #465, #441, #439. Partially resolves #429 and #606. --- include/clad/Differentiator/CladUtils.h | 23 +- include/clad/Differentiator/Compatibility.h | 14 + include/clad/Differentiator/DiffPlanner.h | 2 + .../clad/Differentiator/ReverseModeVisitor.h | 54 +- .../ReverseModeVisitorDirectionKinds.h | 2 +- include/clad/Differentiator/StmtClone.h | 9 +- include/clad/Differentiator/VisitorBase.h | 20 +- lib/Differentiator/CMakeLists.txt | 1 + lib/Differentiator/CladUtils.cpp | 104 +- lib/Differentiator/ErrorEstimator.cpp | 28 +- lib/Differentiator/ReverseModeVisitor.cpp | 974 +++++++++++------- lib/Differentiator/StmtClone.cpp | 17 +- lib/Differentiator/TBRAnalyzer.cpp | 824 +++++++++++++++ lib/Differentiator/TBRAnalyzer.h | 320 ++++++ lib/Differentiator/VisitorBase.cpp | 15 +- test/Analyses/TBR.cpp | 26 + test/Arrays/ArrayInputsReverseMode.C | 204 ++-- test/Arrays/Arrays.C | 26 +- test/CUDA/GradientCuda.cu | 96 +- test/Enzyme/DifferentCladEnzymeDerivatives.C | 12 +- .../LoopsReverseModeComparisonWithClad.C | 12 +- test/ErrorEstimation/Assignments.C | 44 +- test/ErrorEstimation/BasicOps.C | 219 ++-- test/ErrorEstimation/ConditonalStatements.C | 83 +- test/ErrorEstimation/LoopsAndArrays.C | 181 ++-- test/ErrorEstimation/LoopsAndArraysExec.C | 95 +- test/FirstDerivative/BuiltinDerivatives.C | 40 +- test/FirstDerivative/FunctionCalls.C | 2 +- test/FirstDerivative/UnsupportedOpsWarn.C | 1 + test/Gradient/Assignments.C | 413 +++++--- test/Gradient/DiffInterface.C | 80 +- test/Gradient/FunctionCalls.C | 215 ++-- test/Gradient/Functors.C | 175 +--- test/Gradient/Gradients.C | 412 +++----- test/Gradient/Loops.C | 732 +++++++------ test/Gradient/MemberFunctions.C | 510 +++------ test/Gradient/Pointers.C | 11 +- test/Gradient/TemplateFunctors.C | 130 +-- test/Gradient/TestAgainstDiff.C | 2 + test/Gradient/TestTypeConversion.C | 14 +- test/Gradient/UserDefinedTypes.C | 300 +++--- test/Gradient/constexprTest.C | 48 +- test/Hessian/Arrays.C | 2 + test/Hessian/BuiltinDerivatives.C | 212 ++-- test/Hessian/Functors.C | 2 + test/Hessian/Hessians.C | 170 +-- test/Hessian/NestedFunctionCalls.C | 74 +- test/Hessian/Pointers.C | 34 +- test/Hessian/TemplateFunctors.C | 2 + test/Hessian/constexprTest.C | 2 + test/Hessian/testhessUtility.C | 2 + test/Jacobian/FunctionCalls.C | 14 +- test/Jacobian/Functors.C | 354 ++----- test/Jacobian/Jacobian.C | 218 +--- test/Jacobian/Pointers.C | 2 + test/Jacobian/TemplateFunctors.C | 122 +-- test/Jacobian/constexprTest.C | 90 +- test/Jacobian/testUtility.C | 90 +- test/Misc/RunDemos.C | 46 +- test/NestedCalls/NestedCalls.C | 40 +- test/NumericalDiff/GradientMultiArg.C | 14 +- test/NumericalDiff/NoNumDiff.C | 2 - test/NumericalDiff/NumDiff.C | 4 +- test/NumericalDiff/PrintErrorNumDiff.C | 8 +- test/ROOT/Hessian.C | 2 + test/ROOT/Interface.C | 10 +- test/ROOT/TFormula.C | 18 +- test/lit.cfg | 2 +- tools/ClangPlugin.cpp | 6 + tools/ClangPlugin.h | 7 +- 70 files changed, 4252 insertions(+), 3787 deletions(-) create mode 100644 lib/Differentiator/TBRAnalyzer.cpp create mode 100644 lib/Differentiator/TBRAnalyzer.h create mode 100644 test/Analyses/TBR.cpp diff --git a/include/clad/Differentiator/CladUtils.h b/include/clad/Differentiator/CladUtils.h index baf8649eb..0e5a6d308 100644 --- a/include/clad/Differentiator/CladUtils.h +++ b/include/clad/Differentiator/CladUtils.h @@ -28,7 +28,7 @@ namespace clad { std::string ComputeEffectiveFnName(const clang::FunctionDecl* FD); /// Creates and returns a compound statement having statements as follows: - /// {`S`, all the statement of `initial` in sequence} + /// {`S`, all the statement of `initial` in sequence} clang::CompoundStmt* PrependAndCreateCompoundStmt(clang::ASTContext& C, clang::Stmt* initial, clang::Stmt* S); @@ -38,7 +38,7 @@ namespace clad { clang::CompoundStmt* AppendAndCreateCompoundStmt(clang::ASTContext& C, clang::Stmt* initial, clang::Stmt* S); - + /// Shorthand to issues a warning or error. template void EmitDiag(clang::Sema& semaRef, @@ -126,8 +126,8 @@ namespace clad { /// /// \param S /// \param namespc - /// \param shouldExist If true, then asserts that the specified namespace - /// is found. + /// \param shouldExist If true, then asserts that the specified namespace + /// is found. /// \param DC clang::NamespaceDecl* LookupNSD(clang::Sema& S, llvm::StringRef namespc, bool shouldExist, @@ -162,7 +162,10 @@ namespace clad { llvm::StringRef str); /// Returns true if `QT` is Array or Pointer Type, otherwise returns false. - bool isArrayOrPointerType(const clang::QualType QT); + bool isArrayOrPointerType(clang::QualType QT); + + /// Returns true if `T` is auto or auto* type, otherwise returns false. + bool IsAutoOrAutoPtrType(clang::QualType T); clang::DeclarationNameInfo BuildDeclarationNameInfo(clang::Sema& S, llvm::StringRef name); @@ -234,7 +237,7 @@ namespace clad { bool IsCladValueAndPushforwardType(clang::QualType T); - /// Returns a valid `SourceRange` to be used in places where clang + /// Returns a valid `SourceRange` to be used in places where clang /// requires a valid `SourceRange`. clang::SourceRange GetValidSRange(clang::Sema& semaRef); @@ -313,6 +316,14 @@ namespace clad { bool hasNonDifferentiableAttribute(const clang::Decl* D); bool hasNonDifferentiableAttribute(const clang::Expr* E); + + /// Collects every DeclRefExpr, MemberExpr, ArraySubscriptExpr in an + /// assignment operator or a ternary if operator. This is useful to when we + /// need to decide what needs to be stored on tape in reverse mode. + void GetInnermostReturnExpr(const clang::Expr* E, + llvm::SmallVectorImpl& Exprs); + + bool ContainsFunctionCalls(const clang::Stmt* E); } // namespace utils } diff --git a/include/clad/Differentiator/Compatibility.h b/include/clad/Differentiator/Compatibility.h index 3c237606c..0ac2dcbdc 100644 --- a/include/clad/Differentiator/Compatibility.h +++ b/include/clad/Differentiator/Compatibility.h @@ -133,6 +133,20 @@ static inline bool Expr_EvaluateAsInt(const Expr *E, #endif } +// Clang 12: bool Expr::EvaluateAsConstantExpr(EvalResult &Result, +// ConstExprUsage Usage, ASTContext &) +// => bool Expr::EvaluateAsConstantExpr(EvalResult &Result, ASTContext &) + +static inline bool Expr_EvaluateAsConstantExpr(const Expr* E, + Expr::EvalResult& res, + const ASTContext& Ctx) { +#if CLANG_VERSION_MAJOR < 12 + return E->EvaluateAsConstantExpr(res, Expr::EvaluateForCodeGen, Ctx); +#else + return E->EvaluateAsConstantExpr(res, Ctx); +#endif +} + // Compatibility helper function for creation IfStmt. // Clang 8 and above use Create. // Clang 12 and above use two extra params. diff --git a/include/clad/Differentiator/DiffPlanner.h b/include/clad/Differentiator/DiffPlanner.h index bd51548e6..2705cc447 100644 --- a/include/clad/Differentiator/DiffPlanner.h +++ b/include/clad/Differentiator/DiffPlanner.h @@ -43,6 +43,8 @@ namespace clad { bool CallUpdateRequired = false; /// A flag to enable/disable diag warnings/errors during differentiation. bool VerboseDiags = false; + /// A flag to enable TBR analysis during reverse-mode differentiation. + bool EnableTBRAnalysis = false; /// Puts the derived function and its code in the diff call void updateCall(clang::FunctionDecl* FD, clang::FunctionDecl* OverloadedFD, clang::Sema& SemaRef); diff --git a/include/clad/Differentiator/ReverseModeVisitor.h b/include/clad/Differentiator/ReverseModeVisitor.h index 64dcb52af..c49b8c0d8 100644 --- a/include/clad/Differentiator/ReverseModeVisitor.h +++ b/include/clad/Differentiator/ReverseModeVisitor.h @@ -50,19 +50,20 @@ namespace clad { Stmts m_Globals; //// A reference to the output parameter of the gradient function. clang::Expr* m_Result; + /// Based on To-Be-Recorded analysis performed before differentiation, + /// tells UsefulToStoreGlobal whether a variable with a given + /// SourceLocation has to be stored before being changed or not. + std::set m_ToBeRecorded; /// A flag indicating if the Stmt we are currently visiting is inside loop. bool isInsideLoop = false; /// Output variable of vector-valued function std::string outputArrayStr; - /// Stores the pop index values for arrays in reverse mode.This is required - /// to maintain the correct statement order when the current block has - /// delayed emission i.e. assignment LHS. - Stmts m_PopIdxValues; std::vector m_LoopBlock; unsigned outputArrayCursor = 0; unsigned numParams = 0; bool isVectorValued = false; bool use_enzyme = false; + bool enableTBR = false; // FIXME: Should we make this an object instead of a pointer? // Downside of making it an object: We will need to include // 'MultiplexExternalRMVSource.h' file @@ -142,24 +143,33 @@ namespace clad { /// Create new block. Stmts& beginBlock(direction d = direction::forward) { if (d == direction::forward) - m_Blocks.push_back({}); + m_Blocks.emplace_back(); else - m_Reverse.push_back({}); + m_Reverse.emplace_back(); return getCurrentBlock(d); } /// Remove the block from the stack, wrap it in CompoundStmt and return it. clang::CompoundStmt* endBlock(direction d = direction::forward) { if (d == direction::forward) { - auto CS = MakeCompoundStmt(getCurrentBlock(direction::forward)); + auto* CS = MakeCompoundStmt(getCurrentBlock(direction::forward)); m_Blocks.pop_back(); return CS; } else { - auto CS = MakeCompoundStmt(getCurrentBlock(direction::reverse)); + auto* CS = MakeCompoundStmt(getCurrentBlock(direction::reverse)); std::reverse(CS->body_begin(), CS->body_end()); m_Reverse.pop_back(); return CS; } } + + Stmts EndBlockWithoutCreatingCS(direction d = direction::forward) { + auto blk = getCurrentBlock(d); + if (d == direction::forward) + m_Blocks.pop_back(); + else + m_Reverse.pop_back(); + return blk; + } /// Output a statement to the current block. If Stmt is null or is an unused /// expression, it is not output and false is returned. bool addToCurrentBlock(clang::Stmt* S, direction d = direction::forward) { @@ -237,6 +247,10 @@ namespace clad { StmtDiff GlobalStoreAndRef(clang::Expr* E, llvm::StringRef prefix = "_t", bool force = false); + StmtDiff BuildPushPop(clang::Expr* E, clang::QualType Type, + llvm::StringRef prefix = "_t", bool force = false); + StmtDiff StoreAndRestore(clang::Expr* E, llvm::StringRef prefix = "_t", + bool force = false); //// A type returned by DelayedGlobalStoreAndRef /// .Result is a reference to the created (yet uninitialized) global @@ -250,6 +264,12 @@ namespace clad { StmtDiff Result; bool isConstant; bool isInsideLoop; + bool needsUpdate; + DelayedStoreResult(ReverseModeVisitor& pV, StmtDiff pResult, + bool pIsConstant, bool pIsInsideLoop, + bool pNeedsUpdate = false) + : V(pV), Result(pResult), isConstant(pIsConstant), + isInsideLoop(pIsInsideLoop), needsUpdate(pNeedsUpdate) {} void Finalize(clang::Expr* New); }; @@ -393,7 +413,7 @@ namespace clad { clang::QualType xType); /// Allows to easily create and manage a counter for counting the number of - /// executed iterations of a loop. + /// executed iterations of a loop. /// /// It is required to save the number of executed iterations to use the /// same number of iterations in the reverse pass. @@ -412,11 +432,11 @@ namespace clad { /// for counter; otherwise, returns nullptr. clang::Expr* getPush() const { return m_Push; } - /// Returns `clad::pop(_t)` expression if clad tape is used for + /// Returns `clad::pop(_t)` expression if clad tape is used for /// for counter; otherwise, returns nullptr. clang::Expr* getPop() const { return m_Pop; } - /// Returns reference to the last object of the clad tape if clad tape + /// Returns reference to the last object of the clad tape if clad tape /// is used as the counter; otherwise returns reference to the counter /// variable. clang::Expr* getRef() const { return m_Ref; } @@ -458,11 +478,11 @@ namespace clad { /// This class modifies forward and reverse blocks of the loop /// body so that `break` and `continue` statements are correctly - /// handled. `break` and `continue` statements are handled by + /// handled. `break` and `continue` statements are handled by /// enclosing entire reverse block loop body in a switch statement /// and only executing the statements, with the help of case labels, - /// that were executed in the associated forward iteration. This is - /// determined by keeping track of which `break`/`continue` statement + /// that were executed in the associated forward iteration. This is + /// determined by keeping track of which `break`/`continue` statement /// was hit in which iteration and that in turn helps to determine which /// case label should be selected. /// @@ -490,7 +510,7 @@ namespace clad { /// \note `m_ControlFlowTape` is only initialized if the body contains /// `continue` or `break` statement. std::unique_ptr m_ControlFlowTape; - + /// Each `break` and `continue` statement is assigned a unique number, /// starting from 1, that is used as the case label corresponding to that `break`/`continue` /// statement. `m_CaseCounter` stores the value that was used for last @@ -529,7 +549,7 @@ namespace clad { /// control flow switch statement. clang::CaseStmt* GetNextCFCaseStmt(); - /// Builds and returns `clad::push(TapeRef, m_CurrentCounter)` + /// Builds and returns `clad::push(TapeRef, m_CurrentCounter)` /// expression, where `TapeRef` and `m_CurrentCounter` are replaced /// by their actual values respectively. clang::Stmt* CreateCFTapePushExprToCurrentCase(); @@ -552,7 +572,7 @@ namespace clad { void PopBreakContStmtHandler() { m_BreakContStmtHandlers.pop_back(); } - + /// Registers an external RMV source. /// /// Multiple external RMV source can be registered by calling this function diff --git a/include/clad/Differentiator/ReverseModeVisitorDirectionKinds.h b/include/clad/Differentiator/ReverseModeVisitorDirectionKinds.h index 449a996a7..f75b5301d 100644 --- a/include/clad/Differentiator/ReverseModeVisitorDirectionKinds.h +++ b/include/clad/Differentiator/ReverseModeVisitorDirectionKinds.h @@ -4,7 +4,7 @@ namespace clad { namespace rmv { /// An enum to operate between forward and reverse passes. - enum direction : int { forward, reverse }; + enum direction : int { forward, reverse }; } // namespace rmv } // namespace clad diff --git a/include/clad/Differentiator/StmtClone.h b/include/clad/Differentiator/StmtClone.h index cf32b813f..ee2bdd25b 100644 --- a/include/clad/Differentiator/StmtClone.h +++ b/include/clad/Differentiator/StmtClone.h @@ -15,6 +15,7 @@ #include "clang/Sema/Scope.h" #include "llvm/ADT/DenseMap.h" +#include namespace clang { class Stmt; @@ -153,9 +154,13 @@ namespace utils { clang::Sema& m_Sema; // We don't own. clang::Scope* m_CurScope; // We don't own. const clang::FunctionDecl* m_Function; // We don't own. + const std::unordered_map& + m_DeclReplacements; // We don't own. public: - ReferencesUpdater(clang::Sema& SemaRef, clang::Scope* S, - const clang::FunctionDecl* FD); + ReferencesUpdater( + clang::Sema& SemaRef, clang::Scope* S, const clang::FunctionDecl* FD, + const std::unordered_map& + DeclReplacements); bool VisitDeclRefExpr(clang::DeclRefExpr* DRE); bool VisitStmt(clang::Stmt* S); /// Used to update the size expression of QT diff --git a/include/clad/Differentiator/VisitorBase.h b/include/clad/Differentiator/VisitorBase.h index 08a6201f8..09a7af293 100644 --- a/include/clad/Differentiator/VisitorBase.h +++ b/include/clad/Differentiator/VisitorBase.h @@ -33,10 +33,14 @@ namespace clad { private: std::array data; clang::Stmt* m_DerivativeForForwSweep; + clang::Stmt* m_ValueForRevSweep; + public: StmtDiff(clang::Stmt* orig = nullptr, clang::Stmt* diff = nullptr, - clang::Stmt* forwSweepDiff = nullptr) - : m_DerivativeForForwSweep(forwSweepDiff) { + clang::Stmt* forwSweepDiff = nullptr, + clang::Stmt* valueForRevSweep = nullptr) + : m_DerivativeForForwSweep(forwSweepDiff), + m_ValueForRevSweep(valueForRevSweep) { data[1] = orig; data[0] = diff; } @@ -57,6 +61,18 @@ namespace clad { clang::Stmt* getForwSweepStmt_dx() { return m_DerivativeForForwSweep; } + clang::Expr* getRevSweepAsExpr() { + return llvm::cast_or_null(getRevSweepStmt()); + } + + clang::Stmt* getRevSweepStmt() { + /// If there is no specific value for + /// the reverse sweep, use Stmt_dx. + if (!m_ValueForRevSweep) + return data[1]; + return m_ValueForRevSweep; + } + clang::Expr* getForwSweepExpr_dx() { return llvm::cast_or_null(m_DerivativeForForwSweep); } diff --git a/lib/Differentiator/CMakeLists.txt b/lib/Differentiator/CMakeLists.txt index f5eddb2c6..d778be998 100644 --- a/lib/Differentiator/CMakeLists.txt +++ b/lib/Differentiator/CMakeLists.txt @@ -33,6 +33,7 @@ add_llvm_library(cladDifferentiator MultiplexExternalRMVSource.cpp ReverseModeForwPassVisitor.cpp ReverseModeVisitor.cpp + TBRAnalyzer.cpp StmtClone.cpp VectorForwardModeVisitor.cpp Version.cpp diff --git a/lib/Differentiator/CladUtils.cpp b/lib/Differentiator/CladUtils.cpp index d1a435848..a49d52477 100644 --- a/lib/Differentiator/CladUtils.cpp +++ b/lib/Differentiator/CladUtils.cpp @@ -5,10 +5,11 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/Lookup.h" -#include "clad/Differentiator/Compatibility.h" #include "llvm/ADT/SmallVector.h" +#include "clad/Differentiator/Compatibility.h" using namespace clang; namespace clad { @@ -109,7 +110,7 @@ namespace clad { CompoundStmt* CS = dyn_cast(initial); if (CS) block.append(CS->body_begin(), CS->body_end()); - else + else block.push_back(initial); auto stmtsRef = clad_compat::makeArrayRef(block.begin(), block.end()); return clad_compat::CompoundStmt_Create(C, stmtsRef /**/CLAD_COMPAT_CLANG15_CompoundStmt_Create_ExtraParam1(CS), noLoc, noLoc); @@ -183,7 +184,7 @@ namespace clad { if (isa(DC2)) break; if (isa(DC2)) { - DC2 = DC2->getParent(); + DC2 = DC2->getParent(); continue; } if (DC2->isInlineNamespace()) { @@ -262,7 +263,7 @@ namespace clad { } return DC; } - + StringLiteral* CreateStringLiteral(ASTContext& C, llvm::StringRef str) { // Copied and adapted from clang::Sema::ActOnStringLiteral. QualType CharTyConst = C.CharTy.withConst(); @@ -279,7 +280,7 @@ namespace clad { return SL; } - bool isArrayOrPointerType(const clang::QualType QT) { + bool isArrayOrPointerType(clang::QualType QT) { return QT->isArrayType() || QT->isPointerType(); } @@ -355,10 +356,10 @@ namespace clad { QualType valueType = T; if (T->isPointerType()) valueType = T->getPointeeType(); - else if (T->isReferenceType()) + else if (T->isReferenceType()) valueType = T.getNonReferenceType(); // FIXME: `QualType::getPointeeOrArrayElementType` loses type qualifiers. - else if (T->isArrayType()) + else if (T->isArrayType()) valueType = T->getPointeeOrArrayElementType()->getCanonicalTypeInternal(); valueType.removeLocalConst(); @@ -437,7 +438,7 @@ namespace clad { else if (S) block.push_back(S); } - + MemberExpr* BuildMemberExpr(clang::Sema& semaRef, clang::Scope* S, clang::Expr* base, llvm::ArrayRef fields) { @@ -543,5 +544,92 @@ namespace clad { // non-differentiable attribute return false; } + + void GetInnermostReturnExpr(const clang::Expr* E, + llvm::SmallVectorImpl& Exprs) { + struct Finder : public StmtVisitor { + llvm::SmallVectorImpl& m_Exprs; + + public: + Finder(clang::Expr* E, llvm::SmallVectorImpl& Exprs) + : m_Exprs(Exprs) { + Visit(E); + } + + void VisitBinaryOperator(clang::BinaryOperator* BO) { + if (BO->isAssignmentOp() || BO->isCompoundAssignmentOp()) { + Visit(BO->getLHS()); + } else if (BO->getOpcode() == clang::BO_Comma) { + /**/ + } else { + assert("Unexpected binary operator!!"); + } + } + + void VisitConditionalOperator(clang::ConditionalOperator* CO) { + // FIXME: in cases like (cond ? x : y) = 2; both x and y will be + // stored. + Visit(CO->getTrueExpr()); + Visit(CO->getFalseExpr()); + } + + void VisitUnaryOperator(clang::UnaryOperator* UnOp) { + auto opCode = UnOp->getOpcode(); + if (opCode == clang::UO_PreInc || opCode == clang::UO_PreDec) + Visit(UnOp->getSubExpr()); + else if (opCode == UnaryOperatorKind::UO_Real || + opCode == UnaryOperatorKind::UO_Imag) { + /// FIXME: Considering real/imaginary part atomic is + /// not always correct since the subexpression can + /// be more complex than just a DeclRefExpr. + /// (e.g. `__real (n++ ? z1 : z2)`) + m_Exprs.push_back(UnOp); + } + } + + void VisitDeclRefExpr(clang::DeclRefExpr* DRE) { + m_Exprs.push_back(DRE); + } + + void VisitParenExpr(clang::ParenExpr* PE) { Visit(PE->getSubExpr()); } + + void VisitMemberExpr(clang::MemberExpr* ME) { m_Exprs.push_back(ME); } + + void VisitArraySubscriptExpr(clang::ArraySubscriptExpr* ASE) { + m_Exprs.push_back(ASE); + } + + void VisitImplicitCastExpr(clang::ImplicitCastExpr* ICE) { + Visit(ICE->getSubExpr()); + } + }; + // FIXME: Fix the constness on the callers of this function. + Finder finder(const_cast(E), Exprs); + } + + bool IsAutoOrAutoPtrType(QualType T) { + if (isa(T)) + return true; + + if (const auto* const pointerType = dyn_cast(T)) + return IsAutoOrAutoPtrType(pointerType->getPointeeType()); + + return false; + } + + bool ContainsFunctionCalls(const clang::Stmt* S) { + class CallExprFinder : public RecursiveASTVisitor { + public: + bool hasCallExpr = false; + + bool VisitCallExpr(CallExpr* CE) { + hasCallExpr = true; + return false; + } + }; + CallExprFinder finder; + finder.TraverseStmt(const_cast(S)); + return finder.hasCallExpr; + } } // namespace utils } // namespace clad diff --git a/lib/Differentiator/ErrorEstimator.cpp b/lib/Differentiator/ErrorEstimator.cpp index c2a2dd49e..cbab2a49e 100644 --- a/lib/Differentiator/ErrorEstimator.cpp +++ b/lib/Differentiator/ErrorEstimator.cpp @@ -83,33 +83,9 @@ void ErrorEstimationHandler::BuildFinalErrorStmt() { void ErrorEstimationHandler::AddErrorStmtToBlock(Expr* var, Expr* deltaVar, Expr* errorExpr, bool isInsideLoop /*=false*/) { + if (auto ASE = dyn_cast(var)) { - // If inside loop, the index has been pushed twice - // (once by ArraySubscriptExpr and the second time by us) - // pop and store it in a temporary variable to reuse later. - // FIXME: build add assign into he same expression i.e. - // _final_error += _delta_arr[pop(_t0)] += <-Error Expr-> - // to avoid storage of the pop value. - Expr* popVal = ASE->getIdx(); - if (isInsideLoop) { - LookupResult& Pop = m_RMV->GetCladTapePop(); - CXXScopeSpec CSS; - CSS.Extend(m_RMV->m_Context, m_RMV->GetCladNamespace(), noLoc, noLoc); - auto PopDRE = m_RMV->m_Sema - .BuildDeclarationNameExpr(CSS, Pop, - /*AcceptInvalidDecl=*/false) - .get(); - Expr* tapeRef = dyn_cast(popVal)->getArg(0); - popVal = m_RMV->m_Sema - .ActOnCallExpr(m_RMV->getCurrentScope(), PopDRE, noLoc, - tapeRef, noLoc) - .get(); - popVal = m_RMV->StoreAndRef(popVal, direction::reverse); - } - // If the variable declration refers to an array element - // create the suitable _delta_arr[i] (because we have not done - // this before). - deltaVar = getArraySubscriptExpr(deltaVar, popVal); + deltaVar = getArraySubscriptExpr(deltaVar, ASE->getIdx()); m_RMV->addToCurrentBlock(m_RMV->BuildOp(BO_AddAssign, deltaVar, errorExpr), direction::reverse); // immediately emit fin_err += delta_[]. diff --git a/lib/Differentiator/ReverseModeVisitor.cpp b/lib/Differentiator/ReverseModeVisitor.cpp index cd39fb06f..d83cd3f8d 100644 --- a/lib/Differentiator/ReverseModeVisitor.cpp +++ b/lib/Differentiator/ReverseModeVisitor.cpp @@ -8,11 +8,12 @@ #include "ConstantFolder.h" +#include "TBRAnalyzer.h" #include "clad/Differentiator/DiffPlanner.h" #include "clad/Differentiator/ErrorEstimator.h" -#include "clad/Differentiator/StmtClone.h" #include "clad/Differentiator/ExternalRMVSource.h" #include "clad/Differentiator/MultiplexExternalRMVSource.h" +#include "clad/Differentiator/StmtClone.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" @@ -38,10 +39,10 @@ namespace clad { Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, ReverseModeVisitor& rvm) { - if (auto CAT = dyn_cast(AT)) + if (const auto* const CAT = dyn_cast(AT)) return ConstantFolder::synthesizeLiteral(context.getSizeType(), context, CAT->getSize().getZExtValue()); - else if (auto VSAT = dyn_cast(AT)) + if (const auto* VSAT = dyn_cast(AT)) return rvm.Clone(VSAT->getSizeExpr()); return nullptr; @@ -64,45 +65,30 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, ReverseModeVisitor::CladTapeResult ReverseModeVisitor::MakeCladTapeFor(Expr* E, llvm::StringRef prefix) { assert(E && "must be provided"); - if (auto IE = dyn_cast(E)) { - E = IE->getSubExpr()->IgnoreImplicit(); - } - QualType EQt = E->getType(); - if (dyn_cast(EQt)) - EQt = GetCladArrayOfType(utils::GetValueType(EQt)); + E = E->IgnoreImplicit(); QualType TapeType = - GetCladTapeOfType(getNonConstType(EQt, m_Context, m_Sema)); + GetCladTapeOfType(getNonConstType(E->getType(), m_Context, m_Sema)); LookupResult& Push = GetCladTapePush(); LookupResult& Pop = GetCladTapePop(); Expr* TapeRef = BuildDeclRef(GlobalStoreImpl(TapeType, prefix, getZeroInit(TapeType))); - auto VD = cast(cast(TapeRef)->getDecl()); + auto* VD = cast(cast(TapeRef)->getDecl()); // Add fake location, since Clang AST does assert(Loc.isValid()) somewhere. VD->setLocation(m_Function->getLocation()); CXXScopeSpec CSS; CSS.Extend(m_Context, GetCladNamespace(), noLoc, noLoc); - auto PopDRE = m_Sema - .BuildDeclarationNameExpr(CSS, Pop, - /*AcceptInvalidDecl=*/false) - .get(); - auto PushDRE = m_Sema - .BuildDeclarationNameExpr(CSS, Push, + auto* PopDRE = m_Sema + .BuildDeclarationNameExpr(CSS, Pop, /*AcceptInvalidDecl=*/false) .get(); + auto* PushDRE = m_Sema + .BuildDeclarationNameExpr(CSS, Push, + /*AcceptInvalidDecl=*/false) + .get(); Expr* PopExpr = m_Sema.ActOnCallExpr(getCurrentScope(), PopDRE, noLoc, TapeRef, noLoc) .get(); - Expr* exprToPush = E; - if (auto AT = dyn_cast(E->getType())) { - Expr* init = getArraySizeExpr(AT, m_Context, *this); - llvm::SmallVector pushArgs{E, init}; - SourceLocation loc = E->getExprLoc(); - TypeSourceInfo* TSI = m_Context.getTrivialTypeSourceInfo(EQt, loc); - exprToPush = - m_Sema.BuildCXXTypeConstructExpr(TSI, loc, pushArgs, loc, false) - .get(); - } - Expr* CallArgs[] = {TapeRef, exprToPush}; + Expr* CallArgs[] = {TapeRef, E}; Expr* PushExpr = m_Sema.ActOnCallExpr(getCurrentScope(), PushDRE, noLoc, CallArgs, noLoc) .get(); @@ -148,7 +134,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, llvm::SmallVector paramTypes; // Add types for representing original function parameters. - for (auto PVD : m_Function->parameters()) + for (auto* PVD : m_Function->parameters()) paramTypes.push_back(PVD->getType()); // Add types for representing parameter derivatives. // FIXME: We are assuming all function parameters are differentiable. We @@ -163,7 +149,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // Cast to function pointer. gradFuncOverloadEPI); - DeclContext* DC = const_cast(m_Function->getDeclContext()); + auto* DC = const_cast(m_Function->getDeclContext()); m_Sema.CurContext = DC; DeclWithContext gradientOverloadFDWC = m_Builder.cloneFunction(m_Function, *this, DC, noLoc, gradientNameInfo, @@ -181,8 +167,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, overloadParams.reserve(totalDerivedParamsSize); callArgs.reserve(gradientParams.size()); - for (auto PVD : m_Function->parameters()) { - auto VD = utils::BuildParmVarDecl( + for (auto* PVD : m_Function->parameters()) { + auto* VD = utils::BuildParmVarDecl( m_Sema, gradientOverloadFD, PVD->getIdentifier(), PVD->getType(), PVD->getStorageClass(), /*defArg=*/nullptr, PVD->getTypeSourceInfo()); overloadParams.push_back(VD); @@ -197,22 +183,21 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // parameter represents an actual derivative of one of the function // original parameters. if (effectiveGradientIndex < gradientParams.size()) { - auto GVD = gradientParams[effectiveGradientIndex]; + auto* GVD = gradientParams[effectiveGradientIndex]; II = CreateUniqueIdentifier("_temp_" + GVD->getNameAsString()); SC = GVD->getStorageClass(); } else { II = CreateUniqueIdentifier("_d_" + std::to_string(i)); } - auto PVD = utils::BuildParmVarDecl(m_Sema, gradientOverloadFD, II, - outputParamType, SC); + auto* PVD = utils::BuildParmVarDecl(m_Sema, gradientOverloadFD, II, + outputParamType, SC); overloadParams.push_back(PVD); } - for (auto PVD : overloadParams) { + for (auto* PVD : overloadParams) if (PVD->getIdentifier()) m_Sema.PushOnScopeChains(PVD, getCurrentScope(), /*AddToContext=*/false); - } gradientOverloadFD->setParams(overloadParams); gradientOverloadFD->setBody(/*B=*/nullptr); @@ -226,10 +211,10 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // overloaded derived function to the correct type. for (std::size_t i = m_Function->getNumParams(); i < gradientParams.size(); ++i) { - auto overloadParam = overloadParams[i]; - auto gradientParam = gradientParams[i]; + auto* overloadParam = overloadParams[i]; + auto* gradientParam = gradientParams[i]; - auto gradientVD = + auto* gradientVD = BuildVarDecl(gradientParam->getType(), gradientParam->getName(), BuildDeclRef(overloadParam)); callArgs.push_back(BuildDeclRef(gradientVD)); @@ -273,7 +258,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, DiffInputVarsInfo DVI; if (request.Args) { DVI = request.DVI; - for (auto dParam : DVI) + for (const auto& dParam : DVI) args.push_back(dParam.param); } else @@ -291,6 +276,10 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, outputArrayStr = m_Function->getParamDecl(lastArgN)->getNameAsString(); } + // Check if DiffRequest asks for TBR analysis to be enabled + if (request.EnableTBRAnalysis) + enableTBR = true; + // Check if DiffRequest asks for use of enzyme as backend if (request.use_enzyme) use_enzyme = true; @@ -303,16 +292,17 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // If Jacobian is asked, the last parameter is the result parameter // and should be ignored if (args.size() != FD->getNumParams()-1){ - for (auto arg : args) { - auto it = std::find(FD->param_begin(), FD->param_end()-1, arg); + for (const auto* arg : args) { + const auto* const it = + std::find(FD->param_begin(), FD->param_end() - 1, arg); auto idx = std::distance(FD->param_begin(), it); gradientName += ('_' + std::to_string(idx)); } } }else{ if (args.size() != FD->getNumParams()){ - for (auto arg : args) { - auto it = std::find(FD->param_begin(), FD->param_end(), arg); + for (const auto* arg : args) { + const auto* it = std::find(FD->param_begin(), FD->param_end(), arg); auto idx = std::distance(FD->param_begin(), it); gradientName += ('_' + std::to_string(idx)); } @@ -341,7 +331,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, if (!isVectorValued && numExtraParam == 0) shouldCreateOverload = true; - auto originalFnType = dyn_cast(m_Function->getType()); + const auto* originalFnType = + dyn_cast(m_Function->getType()); // For a function f of type R(A1, A2, ..., An), // the type of the gradient function is void(A1, A2, ..., An, R*, R*, ..., // R*) . the type of the jacobian function is void(A1, A2, ..., An, R*, R*) @@ -356,7 +347,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // Create the gradient function declaration. llvm::SaveAndRestore SaveContext(m_Sema.CurContext); llvm::SaveAndRestore SaveScope(m_CurScope); - DeclContext* DC = const_cast(m_Function->getDeclContext()); + auto* DC = const_cast(m_Function->getDeclContext()); m_Sema.CurContext = DC; DeclWithContext result = m_Builder.cloneFunction( m_Function, *this, DC, noLoc, name, gradientFunctionType); @@ -392,7 +383,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // Creates the ArraySubscriptExprs for the independent variables size_t idx = 0; - for (auto arg : args) { + for (const auto* arg : args) { // FIXME: fix when adding array inputs, now we are just skipping all // array/pointer inputs (not treating them as independent variables). if (utils::isArrayOrPointerType(arg->getType())) { @@ -404,11 +395,10 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, auto size_type = m_Context.getSizeType(); unsigned size_type_bits = m_Context.getIntWidth(size_type); // Create the idx literal. - auto i = - IntegerLiteral::Create(m_Context, llvm::APInt(size_type_bits, idx), - size_type, noLoc); + auto* i = IntegerLiteral::Create( + m_Context, llvm::APInt(size_type_bits, idx), size_type, noLoc); // Create the jacobianMatrix[idx] expression. - auto result_at_i = + auto* result_at_i = m_Sema.CreateBuiltinArraySubscriptExpr(m_Result, noLoc, i, noLoc) .get(); m_Variables[arg] = result_at_i; @@ -453,6 +443,22 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, DerivativeAndOverload ReverseModeVisitor::DerivePullback(const clang::FunctionDecl* FD, const DiffRequest& request) { + if (request.EnableTBRAnalysis) + enableTBR = true; + TBRAnalyzer analyzer(m_Context); + if (enableTBR) { + analyzer.Analyze(FD); + m_ToBeRecorded = analyzer.getResult(); + } + + // for (auto pair : m_ToBeRecorded) { + // auto line = + // m_Context.getSourceManager().getPresumedLoc(pair.first).getLine(); auto + // column = + // m_Context.getSourceManager().getPresumedLoc(pair.first).getColumn(); + // llvm::errs() << line << "|" <(m_Function->getType()); + const auto* originalFnType = + dyn_cast(m_Function->getType()); if (m_ExternalSource) m_ExternalSource->ActAfterCreatingDerivedFnParamTypes(paramTypes); @@ -533,12 +540,12 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, for (Stmt* S : m_Globals) addToCurrentBlock(S, direction::forward); // Forward pass. - if (auto CS = dyn_cast(forward)) + if (auto* CS = dyn_cast(forward)) for (Stmt* S : CS->body()) addToCurrentBlock(S, direction::forward); // Reverse pass. - if (auto RCS = dyn_cast(reverse)) + if (auto* RCS = dyn_cast(reverse)) for (Stmt* S : RCS->body()) addToCurrentBlock(S, direction::forward); @@ -556,6 +563,20 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } void ReverseModeVisitor::DifferentiateWithClad() { + TBRAnalyzer analyzer(m_Context); + if (enableTBR) { + analyzer.Analyze(m_Function); + m_ToBeRecorded = analyzer.getResult(); + } + + // for (auto pair : m_ToBeRecorded) { + // auto line = + // m_Context.getSourceManager().getPresumedLoc(pair.first).getLine(); auto + // column = + // m_Context.getSourceManager().getPresumedLoc(pair.first).getColumn(); + // llvm::errs() << line << "|" < paramsRef = m_Derivative->parameters(); // create derived variables for parameters which are not part of @@ -573,7 +594,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // we do not know the correct size. if (utils::isArrayOrPointerType(VDDerivedType)) continue; - auto VDDerived = + auto* VDDerived = BuildVarDecl(VDDerivedType, "_d_" + param->getNameAsString(), getZeroInit(VDDerivedType)); m_Variables[param] = BuildDeclRef(VDDerived); @@ -589,13 +610,13 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, for (Stmt* S : m_Globals) addToCurrentBlock(S, direction::forward); // Forward pass. - if (auto CS = dyn_cast(Forward)) + if (auto* CS = dyn_cast(Forward)) for (Stmt* S : CS->body()) addToCurrentBlock(S, direction::forward); else addToCurrentBlock(Forward, direction::forward); // Reverse pass. - if (auto RCS = dyn_cast(Reverse)) + if (auto* RCS = dyn_cast(Reverse)) for (Stmt* S : RCS->body()) addToCurrentBlock(S, direction::forward); else @@ -609,7 +630,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, unsigned numParams = m_Function->getNumParams(); auto origParams = m_Function->parameters(); llvm::ArrayRef paramsRef = m_Derivative->parameters(); - auto originalFnType = dyn_cast(m_Function->getType()); + const auto* originalFnType = + dyn_cast(m_Function->getType()); // Extract Pointer from Clad Array Ref llvm::SmallVector cladRefParams; @@ -622,9 +644,9 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, paramType = m_Context.getPointerType( QualType(paramType->getPointeeOrArrayElementType(), 0)); - auto arrayRefNameExpr = BuildDeclRef(paramsRef[numParams + i]); - auto getPointerExpr = BuildCallExprToMemFn(arrayRefNameExpr, "ptr", {}); - auto arrayRefToArrayStmt = BuildVarDecl( + auto* arrayRefNameExpr = BuildDeclRef(paramsRef[numParams + i]); + auto* getPointerExpr = BuildCallExprToMemFn(arrayRefNameExpr, "ptr", {}); + auto* arrayRefToArrayStmt = BuildVarDecl( paramType, "d_" + paramsRef[i]->getNameAsString(), getPointerExpr); addToCurrentBlock(BuildDeclStmt(arrayRefToArrayStmt), direction::forward); cladRefParams.push_back(arrayRefToArrayStmt); @@ -637,7 +659,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // First add the function itself as a parameter/argument enzymeArgs.push_back(BuildDeclRef(const_cast(m_Function))); - DeclContext* fdDeclContext = + auto* fdDeclContext = const_cast(m_Function->getDeclContext()); enzymeParams.push_back(m_Sema.BuildParmVarDeclForTypedef( fdDeclContext, noLoc, m_Function->getType())); @@ -669,13 +691,13 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } llvm::SmallVector enzymeParamsType; - for (auto i : enzymeParams) + for (auto* i : enzymeParams) enzymeParamsType.push_back(i->getType()); QualType QT; - if (enzymeRealParams.size()) { + if (!enzymeRealParams.empty()) { // Find the EnzymeGradient datastructure - auto gradDecl = LookupTemplateDeclInCladNamespace("EnzymeGradient"); + auto* gradDecl = LookupTemplateDeclInCladNamespace("EnzymeGradient"); TemplateArgumentListInfo TLI{}; llvm::APSInt argValue(std::to_string(enzymeRealParams.size())); @@ -703,15 +725,15 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // Prepare the statements that assign the gradients to // non array/pointer type parameters of the original function - if (enzymeRealParams.size() != 0) { - auto gradDeclStmt = BuildVarDecl(QT, "grad", enzymeCall, true); + if (!enzymeRealParams.empty()) { + auto* gradDeclStmt = BuildVarDecl(QT, "grad", enzymeCall, true); addToCurrentBlock(BuildDeclStmt(gradDeclStmt), direction::forward); for (unsigned i = 0; i < enzymeRealParams.size(); i++) { - auto LHSExpr = BuildOp(UO_Deref, BuildDeclRef(enzymeRealParamsRef[i])); + auto* LHSExpr = BuildOp(UO_Deref, BuildDeclRef(enzymeRealParamsRef[i])); - auto ME = utils::BuildMemberExpr(m_Sema, getCurrentScope(), - BuildDeclRef(gradDeclStmt), "d_arr"); + auto* ME = utils::BuildMemberExpr(m_Sema, getCurrentScope(), + BuildDeclRef(gradDeclStmt), "d_arr"); Expr* gradIndex = dyn_cast( IntegerLiteral::Create(m_Context, llvm::APSInt(std::to_string(i)), @@ -720,7 +742,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, m_Sema.CreateBuiltinArraySubscriptExpr(ME, noLoc, gradIndex, noLoc) .get(); - auto assignExpr = BuildOp(BO_Assign, LHSExpr, RHSExpr); + auto* assignExpr = BuildOp(BO_Assign, LHSExpr, RHSExpr); addToCurrentBlock(assignExpr, direction::forward); } } else { @@ -763,13 +785,12 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, return nullptr; if (!isa(S)) return S; - auto CS = cast(S); + auto* CS = cast(S); if (CS->size() == 0) return nullptr; - else if (CS->size() == 1) + if (CS->size() == 1) return CS->body_front(); - else - return CS; + return CS; } StmtDiff ReverseModeVisitor::VisitIfStmt(const clang::IfStmt* If) { @@ -799,7 +820,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // skip corresponding push. cond = StoreAndRef(condExpr.getExpr(), direction::forward, "_t", /*forceDeclCreation=*/true); - StmtDiff condPushPop = GlobalStoreAndRef(cond.getExpr(), "_cond"); + StmtDiff condPushPop = GlobalStoreAndRef(cond.getExpr(), "_cond", + /*force=*/true); PushCond = condPushPop.getExpr(); PopCond = condPushPop.getExpr_dx(); } else @@ -860,20 +882,21 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, if (isa(Branch)) { StmtDiff BranchDiff = Visit(Branch); return BranchDiff; - } else { - beginBlock(direction::forward); - if (m_ExternalSource) - m_ExternalSource->ActBeforeDifferentiatingSingleStmtBranchInVisitIfStmt(); - StmtDiff BranchDiff = DifferentiateSingleStmt(Branch, /*dfdS=*/nullptr); - addToCurrentBlock(BranchDiff.getStmt(), direction::forward); + } + beginBlock(direction::forward); + if (m_ExternalSource) + m_ExternalSource + ->ActBeforeDifferentiatingSingleStmtBranchInVisitIfStmt(); + StmtDiff BranchDiff = DifferentiateSingleStmt(Branch, /*dfdS=*/nullptr); + addToCurrentBlock(BranchDiff.getStmt(), direction::forward); - if (m_ExternalSource) - m_ExternalSource->ActBeforeFinalisingVisitBranchSingleStmtInIfVisitStmt(); + if (m_ExternalSource) + m_ExternalSource + ->ActBeforeFinalisingVisitBranchSingleStmtInIfVisitStmt(); - Stmt* Forward = unwrapIfSingleStmt(endBlock(direction::forward)); - Stmt* Reverse = unwrapIfSingleStmt(BranchDiff.getStmt_dx()); - return StmtDiff(Forward, Reverse); - } + Stmt* Forward = unwrapIfSingleStmt(endBlock(direction::forward)); + Stmt* Reverse = unwrapIfSingleStmt(BranchDiff.getStmt_dx()); + return StmtDiff(Forward, Reverse); }; StmtDiff thenDiff = VisitBranch(If->getThen()); @@ -935,8 +958,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, .get() .second; - auto ifTrue = CO->getTrueExpr(); - auto ifFalse = CO->getFalseExpr(); + auto* ifTrue = CO->getTrueExpr(); + auto* ifFalse = CO->getFalseExpr(); auto VisitBranch = [&](const Expr* Branch, Expr* dfdx) -> std::pair { @@ -1031,8 +1054,10 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, VarDecl* condVarClone = nullptr; if (FS->getConditionVariable()) { condVarRes = DifferentiateSingleStmt(FS->getConditionVariableDeclStmt()); - Decl* decl = cast(condVarRes.getStmt())->getSingleDecl(); - condVarClone = cast(decl); + if (isa(condVarRes.getStmt())) { + Decl* decl = cast(condVarRes.getStmt())->getSingleDecl(); + condVarClone = cast(decl); + } } // FIXME: for now we assume that cond has no differentiable effects, @@ -1040,7 +1065,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, StmtDiff cond; if (FS->getCond()) cond = Visit(FS->getCond()); - auto IDRE = dyn_cast(FS->getInc()); + const auto* IDRE = dyn_cast(FS->getInc()); const Expr* inc = IDRE ? Visit(FS->getInc()).getExpr() : FS->getInc(); // Differentiate the increment expression of the for loop @@ -1053,7 +1078,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, std::tie(incDiff, incExprDiff) = DifferentiateSingleExpr(inc); Expr* incResult = nullptr; // If any additional statements were created, enclose them into lambda. - CompoundStmt* Additional = cast(incDiff.getStmt()); + auto* Additional = cast(incDiff.getStmt()); bool anyNonExpr = std::any_of(Additional->body_begin(), Additional->body_end(), [](Stmt* S) { return !isa(S); }); @@ -1083,15 +1108,23 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, incDiff.getStmt_dx(), /*isForLoop=*/true); - Stmt* Forward = new (m_Context) ForStmt(m_Context, - initResult.getStmt(), - cond.getExpr(), - condVarClone, - incResult, - BodyDiff.getStmt(), - noLoc, - noLoc, - noLoc); + /// FIXME: This part in necessary to replace local variables inside loops + /// with function globals and replace initializations with assignments. + /// This is a temporary measure to avoid the bug that arises from + /// overwriting local variables on different loop passes. + Expr* forwardCond = cond.getExpr(); + /// If there is a declaration in the condition, `cond` will be + /// a DeclRefExpr of the declared variable. There is no point in + /// inserting it since condVarRes.getExpr() represents an assignment with + /// that variable on the LHS. + /// e.g. for condition `int x = y`, + /// condVarRes.getExpr() will represent `x = y` + if (condVarRes.getExpr() != nullptr && isa(condVarRes.getExpr())) + forwardCond = cast(condVarRes.getExpr()); + + Stmt* Forward = new (m_Context) + ForStmt(m_Context, initResult.getStmt(), forwardCond, condVarClone, + incResult, BodyDiff.getStmt(), noLoc, noLoc, noLoc); // Create a condition testing counter for being zero, and its decrement. // To match the number of iterations in the forward pass, the reverse loop @@ -1137,7 +1170,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // Initially, df/df = 1. const Expr* value = RS->getRetValue(); QualType type = value->getType(); - auto dfdf = m_Pullback; + auto* dfdf = m_Pullback; if (isa(dfdf) || isa(dfdf)) { ExprResult tmp = dfdf; dfdf = m_Sema @@ -1180,7 +1213,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, StmtDiff ReverseModeVisitor::VisitParenExpr(const ParenExpr* PE) { StmtDiff subStmtDiff = Visit(PE->getSubExpr(), dfdx()); return StmtDiff(BuildParens(subStmtDiff.getExpr()), - BuildParens(subStmtDiff.getExpr_dx())); + BuildParens(subStmtDiff.getExpr_dx()), nullptr, + BuildParens(subStmtDiff.getRevSweepAsExpr())); } StmtDiff ReverseModeVisitor::VisitInitListExpr(const InitListExpr* ILE) { @@ -1200,37 +1234,36 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, Expr* clonedILE = m_Sema.ActOnInitList(noLoc, clonedExprs, noLoc).get(); return StmtDiff(clonedILE); - } else { - // FIXME: This is a makeshift arrangement to differentiate an InitListExpr - // that represents a ValueAndPushforward type. Ideally this must be - // differentiated at VisitCXXConstructExpr + } + // FIXME: This is a makeshift arrangement to differentiate an InitListExpr + // that represents a ValueAndPushforward type. Ideally this must be + // differentiated at VisitCXXConstructExpr #ifndef NDEBUG - bool isValueAndPushforward = isCladValueAndPushforwardType(ILEType); - assert(isValueAndPushforward && - "Only InitListExpr that represents arrays or ValueAndPushforward " - "Object initialization is supported"); + bool isValueAndPushforward = isCladValueAndPushforwardType(ILEType); + assert(isValueAndPushforward && + "Only InitListExpr that represents arrays or ValueAndPushforward " + "Object initialization is supported"); #endif - // Here we assume that the adjoint expression of the first element in - // InitList is dfdx().value and the adjoint for the second element is - // dfdx().pushforward. At this point the top of the Tape must contain a - // ValueAndPushforward object that represents derivative of the - // ValueAndPushforward object returned by the function whose derivative is - // requested. - Expr* dValueExpr = - utils::BuildMemberExpr(m_Sema, getCurrentScope(), dfdx(), "value"); - StmtDiff clonedValueEI = Visit(ILE->getInit(0), dValueExpr).getExpr(); - clonedExprs[0] = clonedValueEI.getExpr(); - - Expr* dPushforwardExpr = utils::BuildMemberExpr(m_Sema, getCurrentScope(), - dfdx(), "pushforward"); - Expr* clonedPushforwardEI = - Visit(ILE->getInit(1), dPushforwardExpr).getExpr(); - clonedExprs[1] = clonedPushforwardEI; - - Expr* clonedILE = m_Sema.ActOnInitList(noLoc, clonedExprs, noLoc).get(); - return StmtDiff(clonedILE); - } + // Here we assume that the adjoint expression of the first element in + // InitList is dfdx().value and the adjoint for the second element is + // dfdx().pushforward. At this point the top of the Tape must contain a + // ValueAndPushforward object that represents derivative of the + // ValueAndPushforward object returned by the function whose derivative is + // requested. + Expr* dValueExpr = + utils::BuildMemberExpr(m_Sema, getCurrentScope(), dfdx(), "value"); + StmtDiff clonedValueEI = Visit(ILE->getInit(0), dValueExpr).getExpr(); + clonedExprs[0] = clonedValueEI.getExpr(); + + Expr* dPushforwardExpr = utils::BuildMemberExpr(m_Sema, getCurrentScope(), + dfdx(), "pushforward"); + Expr* clonedPushforwardEI = + Visit(ILE->getInit(1), dPushforwardExpr).getExpr(); + clonedExprs[1] = clonedPushforwardEI; + + Expr* clonedILE = m_Sema.ActOnInitList(noLoc, clonedExprs, noLoc).get(); + return StmtDiff(clonedILE); } StmtDiff @@ -1243,27 +1276,16 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, llvm::SmallVector reverseIndices(Indices.size()); llvm::SmallVector forwSweepDerivativeIndices(Indices.size()); for (std::size_t i = 0; i < Indices.size(); i++) { + /// FIXME: Remove redundant indices vectors. StmtDiff IdxDiff = Visit(Indices[i]); - StmtDiff IdxStored = GlobalStoreAndRef(IdxDiff.getExpr()); - if (isInsideLoop) { - // Here we make sure that we are popping each time we push. - // Since the max no of pushes = no. of array index expressions in the - // loop. - Expr* popExpr = IdxStored.getExpr_dx(); - VarDecl* popVal = BuildVarDecl(popExpr->getType(), "_t", popExpr, - /*DirectInit=*/true); - if (dfdx()) - addToCurrentBlock(BuildDeclStmt(popVal), direction::reverse); - else - m_PopIdxValues.push_back(BuildDeclStmt(popVal)); - IdxStored = StmtDiff(IdxStored.getExpr(), BuildDeclRef(popVal)); - } - clonedIndices[i] = IdxStored.getExpr(); - reverseIndices[i] = IdxStored.getExpr_dx(); + clonedIndices[i] = Clone(IdxDiff.getExpr()); + reverseIndices[i] = Clone(IdxDiff.getExpr()); + // reverseIndices[i] = Clone(IdxDiff.getExpr()); forwSweepDerivativeIndices[i] = IdxDiff.getExpr(); } - auto cloned = BuildArraySubscript(BaseDiff.getExpr(), clonedIndices); - + auto* cloned = BuildArraySubscript(BaseDiff.getExpr(), clonedIndices); + auto* valueForRevSweep = + BuildArraySubscript(BaseDiff.getExpr(), reverseIndices); Expr* target = BaseDiff.getExpr_dx(); if (!target) return cloned; @@ -1291,36 +1313,32 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, result = target; // Create the (target += dfdx) statement. if (dfdx()) { - auto add_assign = BuildOp(BO_AddAssign, result, dfdx()); + auto* add_assign = BuildOp(BO_AddAssign, result, dfdx()); // Add it to the body statements. addToCurrentBlock(add_assign, direction::reverse); } - return StmtDiff(cloned, result, forwSweepDerivative); + return StmtDiff(cloned, result, forwSweepDerivative, valueForRevSweep); } StmtDiff ReverseModeVisitor::VisitDeclRefExpr(const DeclRefExpr* DRE) { DeclRefExpr* clonedDRE = nullptr; // Check if referenced Decl was "replaced" with another identifier inside // the derivative - if (auto VD = dyn_cast(DRE->getDecl())) { - auto it = m_DeclReplacements.find(VD); - if (it != std::end(m_DeclReplacements)) - clonedDRE = BuildDeclRef(it->second); - else - clonedDRE = cast(Clone(DRE)); + if (const auto* VD = dyn_cast(DRE->getDecl())) { + clonedDRE = cast(Clone(DRE)); // If current context is different than the context of the original // declaration (e.g. we are inside lambda), rebuild the DeclRefExpr // with Sema::BuildDeclRefExpr. This is required in some cases, e.g. // Sema::BuildDeclRefExpr is responsible for adding captured fields // to the underlying struct of a lambda. if (clonedDRE->getDecl()->getDeclContext() != m_Sema.CurContext) { - auto referencedDecl = cast(clonedDRE->getDecl()); + auto* referencedDecl = cast(clonedDRE->getDecl()); clonedDRE = cast(BuildDeclRef(referencedDecl)); } } else clonedDRE = cast(Clone(DRE)); - if (auto decl = dyn_cast(clonedDRE->getDecl())) { + if (auto* decl = dyn_cast(clonedDRE->getDecl())) { if (isVectorValued) { if (m_VectorOutput.size() <= outputArrayCursor) return StmtDiff(clonedDRE); @@ -1332,7 +1350,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } // Create the (jacobianMatrix[idx] += dfdx) statement. if (dfdx()) { - auto add_assign = BuildOp(BO_AddAssign, it->second, dfdx()); + auto* add_assign = BuildOp(BO_AddAssign, it->second, dfdx()); // Add it to the body statements. addToCurrentBlock(add_assign, direction::reverse); } @@ -1504,7 +1522,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // is done to reduce cloning complexity and only clone once. The type is // same as the call expression as it is the type used to declare the // _gradX array - Expr* dArg; + Expr* dArg = nullptr; QualType argType = utils::GetValueType(arg->getType()); dArg = StoreAndRef(/*E=*/nullptr, argType, direction::reverse, "_r", /*forceDeclCreation=*/true); @@ -1532,7 +1550,17 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, CallArgDx.push_back(argDiff.getExpr_dx()); // Save cloned arg in a "global" variable, so that it is accessible from // the reverse pass. - StmtDiff argDiffStore = GlobalStoreAndRef(argDiff.getExpr()); + // FIXME: At this point, we assume all the variables passed by reference + // may be changed since we have no way to determine otherwise. + // FIXME: We cannot use GlobalStoreAndRef to store a whole array so now + // arrays are not stored. + StmtDiff argDiffStore; + if (passByRef && !argDiff.getExpr()->getType()->isArrayType()) + argDiffStore = + GlobalStoreAndRef(argDiff.getExpr(), "_t", /*force=*/true); + else + argDiffStore = {argDiff.getExpr(), argDiff.getExpr()}; + // We need to pass the actual argument in the cloned call expression, // instead of a temporary, for arguments passed by reference. This is // because, callee function may modify the argument passed as reference @@ -1556,7 +1584,9 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // _t1 = a; // modify(a); // ``` - if (passByRef) { + // FIXME: We cannot use GlobalStoreAndRef to store a whole array so now + // arrays are not stored. + if (passByRef && !argDiff.getExpr()->getType()->isArrayType()) { if (isInsideLoop) { // Add tape push expression. We need to explicitly add it here because // we cannot add it as call expression argument -- we need to pass the @@ -1577,11 +1607,17 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, auto& block = getCurrentBlock(direction::reverse); block.insert(block.begin() + insertionPoint, BuildDeclStmt(argDiffLocalVD)); + // Restore agrs + auto* op = BuildOp(BinaryOperatorKind::BO_Assign, argDiff.getExpr(), + BuildDeclRef(argDiffLocalVD)); + block.insert(block.begin() + insertionPoint + 1, op); + Expr* argDiffLocalE = BuildDeclRef(argDiffLocalVD); - // We added local variable to store result of `clad::pop(...)`. Thus - // we need to correspondingly adjust the insertion point. - insertionPoint += 1; + // We added local variable to store result of `clad::pop(...)` and + // restoration of the original arg. Thus we need to correspondingly + // adjust the insertion point. + insertionPoint += 2; // We cannot use the already existing `argDiff.getExpr()` here because // it will cause inconsistent pushes and pops to the clad tape. // FIXME: Modify `GlobalStoreAndRef` such that its functioning is @@ -1590,6 +1626,15 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, Expr* newArgE = Visit(arg).getExpr(); argDiffStore = {newArgE, argDiffLocalE}; } else { + // Restore args + auto& block = getCurrentBlock(direction::reverse); + auto* op = BuildOp(BinaryOperatorKind::BO_Assign, argDiff.getExpr(), + argDiffStore.getExpr()); + block.insert(block.begin() + insertionPoint, op); + // We added restoration of the original arg. Thus we need to + // correspondingly adjust the insertion point. + insertionPoint += 1; + argDiffStore = {argDiff.getExpr(), argDiffStore.getExpr_dx()}; } } @@ -1673,13 +1718,13 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } } - for (auto argDerivative : CallArgDx) { + for (auto* argDerivative : CallArgDx) { gradVarDecl = nullptr; gradVarExpr = nullptr; gradArgExpr = nullptr; gradVarII = CreateUniqueIdentifier(funcPostfix()); - auto PVD = FD->getParamDecl(idx); + const auto* PVD = FD->getParamDecl(idx); bool passByRef = utils::IsReferenceOrPointerType(PVD->getType()); if (passByRef && isa(CE->getArg(idx))) { // If the argument is a temporary variable, this means that param type @@ -1699,7 +1744,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, isa(argDerivative->getType())) { Expr* init = utils::BuildCladArrayInitByConstArray(m_Sema, argDerivative); - auto derivativeArrayRefVD = BuildVarDecl( + auto* derivativeArrayRefVD = BuildVarDecl( GetCladArrayRefOfType(argDerivative->getType() ->getPointeeOrArrayElementType() ->getCanonicalTypeInternal()), @@ -1735,6 +1780,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, idx++; } Expr* pullback = dfdx(); + if ((pullback == nullptr) && FD->getReturnType()->isLValueReferenceType()) pullback = getZeroInit(FD->getReturnType().getNonReferenceType()); @@ -1783,11 +1829,10 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, if (!OverloadedDerivedFn) { if (FD == m_Function && m_Mode == DiffMode::experimental_pullback) { // Recursive call. - auto selfRef = + auto* selfRef = m_Sema - .BuildDeclarationNameExpr(CXXScopeSpec(), - m_Derivative->getNameInfo(), - m_Derivative) + .BuildDeclarationNameExpr( + CXXScopeSpec(), m_Derivative->getNameInfo(), m_Derivative) .get(); OverloadedDerivedFn = @@ -1809,6 +1854,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, pullbackRequest.Mode = DiffMode::experimental_pullback; // Silence diag outputs in nested derivation process. pullbackRequest.VerboseDiags = false; + pullbackRequest.EnableTBRAnalysis = enableTBR; FunctionDecl* pullbackFD = plugin::ProcessDiffRequest(m_CladPlugin, pullbackRequest); // Clad failed to derive it. // FIXME: Add support for reference arguments to the numerical diff. If @@ -1848,9 +1894,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, block.insert(block.begin(), ArgDeclStmts.begin(), ArgDeclStmts.end()); return StmtDiff(Clone(CE)); - } else { - usingNumericalDiff = true; } + usingNumericalDiff = true; } else if (pullbackFD) { if (baseDiff.getExpr()) { Expr* baseE = baseDiff.getExpr(); @@ -1883,7 +1928,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // Put Result array declaration in the function body. // Call the gradient, passing Result as the last Arg. auto& block = getCurrentBlock(direction::reverse); - auto it = std::begin(block) + insertionPoint; + auto* it = std::begin(block) + insertionPoint; // Insert the _gradX declaration statements it = block.insert(it, ArgDeclStmts.begin(), ArgDeclStmts.end()); @@ -1921,17 +1966,6 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, m_ExternalSource->ActBeforeFinalizingVisitCallExpr( CE, OverloadedDerivedFn, DerivedCallArgs, ArgResultDecls, asGrad); - // FIXME: Why are we cloning args here? We already created different - // expressions for call to original function and call to gradient. - // Re-clone function arguments again, since they are required at 2 places: - // call to gradient and call to original function. At this point, each arg - // is either a simple expression or a reference to a temporary variable. - // Therefore cloning it has constant complexity. - std::transform(std::begin(CallArgs), - std::end(CallArgs), - std::begin(CallArgs), - [this](Expr* E) { return Clone(E); }); - Expr* call = nullptr; QualType returnType = FD->getReturnType(); @@ -2019,7 +2053,9 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, StmtDiff ReverseModeVisitor::VisitUnaryOperator(const UnaryOperator* UnOp) { auto opCode = UnOp->getOpcode(); + Expr* valueForRevPass = nullptr; StmtDiff diff{}; + Expr* E = UnOp->getSubExpr(); // If it is a post-increment/decrement operator, its result is a reference // and we should return it. Expr* ResultRef = nullptr; @@ -2027,23 +2063,41 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // xi = +xj // dxi/dxj = +1.0 // df/dxj += df/dxi * dxi/dxj = df/dxi - diff = Visit(UnOp->getSubExpr(), dfdx()); + diff = Visit(E, dfdx()); else if (opCode == UO_Minus) { // xi = -xj // dxi/dxj = -1.0 // df/dxj += df/dxi * dxi/dxj = -df/dxi - auto d = BuildOp(UO_Minus, dfdx()); - diff = Visit(UnOp->getSubExpr(), d); + auto* d = BuildOp(UO_Minus, dfdx()); + diff = Visit(E, d); } else if (opCode == UO_PostInc || opCode == UO_PostDec) { - diff = Visit(UnOp->getSubExpr(), dfdx()); + diff = Visit(E, dfdx()); + if (UsefulToStoreGlobal(diff.getRevSweepAsExpr())) { + auto op = opCode == UO_PostInc ? UO_PostDec : UO_PostInc; + addToCurrentBlock(BuildOp(op, Clone(diff.getRevSweepAsExpr())), + direction::reverse); + } + ResultRef = diff.getExpr_dx(); + valueForRevPass = diff.getRevSweepAsExpr(); if (m_ExternalSource) m_ExternalSource->ActBeforeFinalisingPostIncDecOp(diff); } else if (opCode == UO_PreInc || opCode == UO_PreDec) { - diff = Visit(UnOp->getSubExpr(), dfdx()); + diff = Visit(E, dfdx()); + if (UsefulToStoreGlobal(diff.getRevSweepAsExpr())) { + auto op = opCode == UO_PreInc ? UO_PreDec : UO_PreInc; + addToCurrentBlock(BuildOp(op, Clone(diff.getRevSweepAsExpr())), + direction::reverse); + } + auto op = opCode == UO_PreInc ? BinaryOperatorKind::BO_Add + : BinaryOperatorKind::BO_Sub; + auto* sum = BuildOp( + op, diff.getRevSweepAsExpr(), + ConstantFolder::synthesizeLiteral(m_Context.IntTy, m_Context, 1)); + valueForRevPass = utils::BuildParenExpr(m_Sema, sum); } else if (opCode == UnaryOperatorKind::UO_Real || opCode == UnaryOperatorKind::UO_Imag) { - diff = VisitWithExplicitNoDfDx(UnOp->getSubExpr()); + diff = VisitWithExplicitNoDfDx(E); ResultRef = BuildOp(opCode, diff.getExpr_dx()); /// Create and add `__real r += dfdx()` expression. if (dfdx()) { @@ -2062,11 +2116,11 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // This code snippet should be removed once reverse mode officially // supports pointers. if (opCode == UnaryOperatorKind::UO_AddrOf) { - if (auto MD = dyn_cast(m_Function)) { + if (const auto* MD = dyn_cast(m_Function)) { if (MD->isInstance()) { auto thisType = clad_compat::CXXMethodDecl_getThisType(m_Sema, MD); if (utils::SameCanonicalType(thisType, UnOp->getType())) { - diff = Visit(UnOp->getSubExpr()); + diff = Visit(E); Expr* cloneE = BuildOp(UnaryOperatorKind::UO_AddrOf, diff.getExpr()); Expr* derivedE = @@ -2082,14 +2136,13 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, if (opCode != UO_LNot) unsupportedOpWarn(UnOp->getEndLoc()); - Expr* subExpr = UnOp->getSubExpr(); - if (isa(subExpr)) - diff = Visit(subExpr); + if (isa(E)) + diff = Visit(E); else - diff = StmtDiff(subExpr); + diff = StmtDiff(E); } Expr* op = BuildOp(opCode, diff.getExpr()); - return StmtDiff(op, ResultRef); + return StmtDiff(op, ResultRef, nullptr, valueForRevPass); } StmtDiff @@ -2097,8 +2150,10 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, auto opCode = BinOp->getOpcode(); StmtDiff Ldiff{}; StmtDiff Rdiff{}; - auto L = BinOp->getLHS(); - auto R = BinOp->getRHS(); + StmtDiff Lstored{}; + Expr* valueForRevPass = nullptr; + auto* L = BinOp->getLHS(); + auto* R = BinOp->getRHS(); // If it is an assignment operator, its result is a reference to LHS and // we should return it. Expr* ResultRef = nullptr; @@ -2118,7 +2173,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, Ldiff = Visit(L, dfdx()); // dxi/xr = -1.0 // df/dxl += df/dxi * dxi/xr = -df/dxi - auto dr = BuildOp(UO_Minus, dfdx()); + auto* dr = BuildOp(UO_Minus, dfdx()); Rdiff = Visit(R, dr); } else if (opCode == BO_Mul) { // xi = xl * xr @@ -2129,11 +2184,21 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // to reduce cloning complexity and only clones once. Storing it in a // global variable allows to save current result and make it accessible // in the reverse pass. - auto RDelayed = DelayedGlobalStoreAndRef(R); - StmtDiff RResult = RDelayed.Result; + std::unique_ptr RDelayed; + StmtDiff RResult; + // If R has no side effects, it can be just cloned + // (no need to store it). + if (utils::ContainsFunctionCalls(R) || R->HasSideEffects(m_Context)) { + RDelayed = std::unique_ptr( + new DelayedStoreResult(DelayedGlobalStoreAndRef(R))); + RResult = RDelayed->Result; + } else { + RResult = StmtDiff(Clone(R)); + } + Expr* dl = nullptr; if (dfdx()) { - dl = BuildOp(BO_Mul, dfdx(), RResult.getExpr_dx()); + dl = BuildOp(BO_Mul, dfdx(), RResult.getRevSweepAsExpr()); dl = StoreAndRef(dl, direction::reverse); } Ldiff = Visit(L, dl); @@ -2141,19 +2206,18 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // df/dxr += df/dxi * dxi/xr = df/dxi * xl // Store left multiplier and assign it with L. Expr* LStored = Ldiff.getExpr(); - // RDelayed.isConstant == true implies that R is a constant expression, - // therefore we can skip visiting it. - if (!RDelayed.isConstant) { + Expr::EvalResult dummy; + if (RDelayed || + !clad_compat::Expr_EvaluateAsConstantExpr(R, dummy, m_Context)) { Expr* dr = nullptr; if (dfdx()) { - StmtDiff LResult = GlobalStoreAndRef(LStored); - LStored = LResult.getExpr(); - dr = BuildOp(BO_Mul, LResult.getExpr_dx(), dfdx()); + dr = BuildOp(BO_Mul, Ldiff.getRevSweepAsExpr(), dfdx()); dr = StoreAndRef(dr, direction::reverse); } Rdiff = Visit(R, dr); // Assign right multiplier's variable with R. - RDelayed.Finalize(Rdiff.getExpr()); + if (RDelayed) + RDelayed->Finalize(Rdiff.getExpr()); } std::tie(Ldiff, Rdiff) = std::make_pair(LStored, RResult.getExpr()); } else if (opCode == BO_Div) { @@ -2173,36 +2237,34 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // df/dxl += df/dxi * dxi/xr = df/dxi * (-xl /(xr * xr)) // Wrap R * R in parentheses: (R * R). otherwise code like 1 / R * R is // produced instead of 1 / (R * R). - Expr* LStored = Ldiff.getExpr(); if (!RDelayed.isConstant) { Expr* dr = nullptr; if (dfdx()) { - StmtDiff LResult = GlobalStoreAndRef(LStored); - LStored = LResult.getExpr(); Expr* RxR = BuildParens(BuildOp(BO_Mul, RStored, RStored)); - dr = BuildOp(BO_Mul, - dfdx(), - BuildOp(UO_Minus, - BuildOp(BO_Div, LResult.getExpr_dx(), RxR))); + dr = + BuildOp(BO_Mul, dfdx(), + BuildOp(UO_Minus, + BuildOp(BO_Div, Ldiff.getRevSweepAsExpr(), RxR))); dr = StoreAndRef(dr, direction::reverse); } Rdiff = Visit(R, dr); RDelayed.Finalize(Rdiff.getExpr()); } - std::tie(Ldiff, Rdiff) = std::make_pair(LStored, RResult.getExpr()); + std::tie(Ldiff, Rdiff) = + std::make_pair(Ldiff.getExpr(), RResult.getExpr()); } else if (BinOp->isAssignmentOp()) { if (L->isModifiableLvalue(m_Context) != Expr::MLV_Valid) { diag(DiagnosticsEngine::Warning, BinOp->getEndLoc(), "derivative of an assignment attempts to assign to unassignable " "expr, assignment ignored"); - auto LDRE = dyn_cast(L); - auto RDRE = dyn_cast(R); + auto* LDRE = dyn_cast(L); + auto* RDRE = dyn_cast(R); if (!LDRE && !RDRE) return Clone(BinOp); - Expr* LExpr = LDRE ? Visit(L).getExpr() : L; - Expr* RExpr = RDRE ? Visit(R).getExpr() : R; + Expr* LExpr = LDRE ? Visit(L).getRevSweepAsExpr() : L; + Expr* RExpr = RDRE ? Visit(R).getRevSweepAsExpr() : R; return BuildOp(opCode, LExpr, RExpr); } @@ -2210,8 +2272,9 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // FIXME: Put this code into a separate subroutine and break out early // using return if the diff mode is not jacobian and we are not dealing // with the `outputArray`. - if (auto ASE = dyn_cast(L)) { - if (auto DRE = dyn_cast(ASE->getBase()->IgnoreImplicit())) { + if (auto* ASE = dyn_cast(L)) { + if (auto* DRE = + dyn_cast(ASE->getBase()->IgnoreImplicit())) { auto type = QualType(DRE->getType()->getPointeeOrArrayElementType(), /*Quals=*/0); std::string DRE_str = DRE->getDecl()->getNameAsString(); @@ -2231,20 +2294,20 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, unsigned size_type_bits = m_Context.getIntWidth(size_type); llvm::APInt idxValue(size_type_bits, i + (outputArrayCursor * numParams)); - auto idx = IntegerLiteral::Create(m_Context, idxValue, - size_type, noLoc); + auto* idx = IntegerLiteral::Create(m_Context, idxValue, + size_type, noLoc); // Create the jacobianMatrix[idx] expression. - auto result_at_i = m_Sema - .CreateBuiltinArraySubscriptExpr( - m_Result, noLoc, idx, noLoc) - .get(); + auto* result_at_i = m_Sema + .CreateBuiltinArraySubscriptExpr( + m_Result, noLoc, idx, noLoc) + .get(); temp_m_Variables[m_IndependentVars[i]] = result_at_i; } m_VectorOutput.push_back(temp_m_Variables); } - auto dfdf = ConstantFolder::synthesizeLiteral(m_Context.IntTy, - m_Context, 1); + auto* dfdf = ConstantFolder::synthesizeLiteral(m_Context.IntTy, + m_Context, 1); ExprResult tmp = dfdf; dfdf = m_Sema .ImpCastExprToType(tmp.get(), type, @@ -2264,7 +2327,16 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // in Lblock beginBlock(direction::reverse); Ldiff = Visit(L, dfdx()); - auto Lblock = endBlock(direction::reverse); + auto* Lblock = endBlock(direction::reverse); + llvm::SmallVector ExprsToStore; + utils::GetInnermostReturnExpr(Ldiff.getExpr(), ExprsToStore); + if (L->HasSideEffects(m_Context)) { + Expr* E = Ldiff.getExpr(); + auto* storeE = + StoreAndRef(E, m_Context.getLValueReferenceType(E->getType())); + Ldiff.updateStmt(storeE); + } + Expr* LCloned = Ldiff.getExpr(); // For x, AssignedDiff is _d_x, for x[i] its _d_x[i], for reference exprs // like (x = y) it propagates recursively, so _d_x is also returned. @@ -2272,8 +2344,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, if (!AssignedDiff) { // If either LHS or RHS is a declaration reference, visit it to avoid // naming collision - auto LDRE = dyn_cast(L); - auto RDRE = dyn_cast(R); + auto* LDRE = dyn_cast(L); + auto* RDRE = dyn_cast(R); if (!LDRE && !RDRE) return Clone(BinOp); @@ -2287,96 +2359,93 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // If assigned expr is dependent, first update its derivative; auto Lblock_begin = Lblock->body_rbegin(); auto Lblock_end = Lblock->body_rend(); - if (dfdx() && Lblock->size()) { + + if (dfdx() && Lblock_begin != Lblock_end) { addToCurrentBlock(*Lblock_begin, direction::reverse); Lblock_begin = std::next(Lblock_begin); } - while(!m_PopIdxValues.empty()) - addToCurrentBlock(m_PopIdxValues.pop_back_val(), direction::reverse); + + for (auto& E : ExprsToStore) { + auto pushPop = StoreAndRestore(E); + addToCurrentBlock(pushPop.getExpr(), direction::forward); + addToCurrentBlock(pushPop.getExpr_dx(), direction::reverse); + } if (m_ExternalSource) m_ExternalSource->ActAfterCloningLHSOfAssignOp(LCloned, R, opCode); // Save old value for the derivative of LHS, to avoid problems with cases // like x = x. - auto oldValue = StoreAndRef(AssignedDiff, direction::reverse, "_r_d", - /*forceDeclCreation=*/true); + auto* oldValue = StoreAndRef(AssignedDiff, direction::reverse, "_r_d", + /*forceDeclCreation=*/true); + if (opCode == BO_Assign) { Rdiff = Visit(R, oldValue); + valueForRevPass = Rdiff.getRevSweepAsExpr(); } else if (opCode == BO_AddAssign) { addToCurrentBlock(BuildOp(BO_AddAssign, AssignedDiff, oldValue), direction::reverse); Rdiff = Visit(R, oldValue); + valueForRevPass = BuildOp(BO_Add, Rdiff.getRevSweepAsExpr(), + Ldiff.getRevSweepAsExpr()); } else if (opCode == BO_SubAssign) { addToCurrentBlock(BuildOp(BO_AddAssign, AssignedDiff, oldValue), direction::reverse); Rdiff = Visit(R, BuildOp(UO_Minus, oldValue)); + valueForRevPass = BuildOp(BO_Sub, Rdiff.getRevSweepAsExpr(), + Ldiff.getRevSweepAsExpr()); } else if (opCode == BO_MulAssign) { - auto RDelayed = DelayedGlobalStoreAndRef(R); - StmtDiff RResult = RDelayed.Result; + // Create a reference variable to keep the result of LHS, since it + // must be used on 2 places: when storing to a global variable + // accessible from the reverse pass, and when rebuilding the original + // expression for the forward pass. This allows to avoid executing + // same expression with side effects twice. E.g., on + // double r = (x *= y) *= z; + // instead of: + // _t0 = (x *= y); + // double r = (x *= y) *= z; + // which modifies x twice, we get: + // double & _ref0 = (x *= y); + // _t0 = _ref0; + // double r = _ref0 *= z; + if (isInsideLoop) + addToCurrentBlock(LCloned, direction::forward); + /// Capture all the emitted statements while visiting R + /// and insert them after `dl += dl * R` + beginBlock(direction::reverse); + Expr* dr = BuildOp(BO_Mul, LCloned, oldValue); + dr = StoreAndRef(dr, direction::reverse); + Rdiff = Visit(R, dr); + Stmts RBlock = EndBlockWithoutCreatingCS(direction::reverse); addToCurrentBlock( - BuildOp(BO_AddAssign, - AssignedDiff, - BuildOp(BO_Mul, oldValue, RResult.getExpr_dx())), + BuildOp(BO_AddAssign, AssignedDiff, + BuildOp(BO_Mul, oldValue, Rdiff.getRevSweepAsExpr())), direction::reverse); - Expr* LRef = LCloned; - if (!RDelayed.isConstant) { - // Create a reference variable to keep the result of LHS, since it - // must be used on 2 places: when storing to a global variable - // accessible from the reverse pass, and when rebuilding the original - // expression for the forward pass. This allows to avoid executing - // same expression with side effects twice. E.g., on - // double r = (x *= y) *= z; - // instead of: - // _t0 = (x *= y); - // double r = (x *= y) *= z; - // which modifies x twice, we get: - // double & _ref0 = (x *= y); - // _t0 = _ref0; - // double r = _ref0 *= z; - if (LCloned->HasSideEffects(m_Context)) { - auto RefType = getNonConstType(L->getType(), m_Context, m_Sema); - LRef = StoreAndRef(LCloned, RefType, direction::forward, "_ref", - /*forceDeclCreation=*/true); - } - StmtDiff LResult = GlobalStoreAndRef(LRef); - if (isInsideLoop) - addToCurrentBlock(LResult.getExpr(), direction::forward); - Expr* dr = BuildOp(BO_Mul, LResult.getExpr_dx(), oldValue); - dr = StoreAndRef(dr, direction::reverse); - Rdiff = Visit(R, dr); - RDelayed.Finalize(Rdiff.getExpr()); - } - std::tie(Ldiff, Rdiff) = std::make_pair(LRef, RResult.getExpr()); + for (auto& S : RBlock) + addToCurrentBlock(S, direction::reverse); + valueForRevPass = BuildOp(BO_Mul, Rdiff.getRevSweepAsExpr(), + Ldiff.getRevSweepAsExpr()); + std::tie(Ldiff, Rdiff) = std::make_pair(LCloned, Rdiff.getExpr()); } else if (opCode == BO_DivAssign) { auto RDelayed = DelayedGlobalStoreAndRef(R); StmtDiff RResult = RDelayed.Result; Expr* RStored = StoreAndRef(RResult.getExpr_dx(), direction::reverse); - addToCurrentBlock(BuildOp(BO_AddAssign, - AssignedDiff, + addToCurrentBlock(BuildOp(BO_AddAssign, AssignedDiff, BuildOp(BO_Div, oldValue, RStored)), direction::reverse); - Expr* LRef = LCloned; if (!RDelayed.isConstant) { - if (LCloned->HasSideEffects(m_Context)) { - QualType RefType = m_Context.getLValueReferenceType( - getNonConstType(L->getType(), m_Context, m_Sema)); - LRef = StoreAndRef(LCloned, RefType, direction::forward, "_ref", - /*forceDeclCreation=*/true); - } - StmtDiff LResult = GlobalStoreAndRef(LRef); if (isInsideLoop) - addToCurrentBlock(LResult.getExpr(), direction::forward); + addToCurrentBlock(LCloned, direction::forward); Expr* RxR = BuildParens(BuildOp(BO_Mul, RStored, RStored)); - Expr* dr = BuildOp( - BO_Mul, - oldValue, - BuildOp(UO_Minus, BuildOp(BO_Div, LResult.getExpr_dx(), RxR))); + Expr* dr = BuildOp(BO_Mul, oldValue, + BuildOp(UO_Minus, BuildOp(BO_Div, LCloned, RxR))); dr = StoreAndRef(dr, direction::reverse); Rdiff = Visit(R, dr); RDelayed.Finalize(Rdiff.getExpr()); } - std::tie(Ldiff, Rdiff) = std::make_pair(LRef, RResult.getExpr()); + valueForRevPass = BuildOp(BO_Div, Rdiff.getRevSweepAsExpr(), + Ldiff.getRevSweepAsExpr()); + std::tie(Ldiff, Rdiff) = std::make_pair(LCloned, RResult.getExpr()); } else llvm_unreachable("unknown assignment opCode"); if (m_ExternalSource) @@ -2388,10 +2457,11 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, for (auto it = Lblock_begin; it != Lblock_end; ++it) addToCurrentBlock(*it, direction::reverse); } else if (opCode == BO_Comma) { - auto zero = + auto* zero = ConstantFolder::synthesizeLiteral(m_Context.IntTy, m_Context, 0); Ldiff = Visit(L, zero); Rdiff = Visit(R, dfdx()); + valueForRevPass = Ldiff.getRevSweepAsExpr(); ResultRef = Ldiff.getExpr(); } else { // We should not output any warning on visiting boolean conditions @@ -2402,8 +2472,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // If either LHS or RHS is a declaration reference, visit it to avoid // naming collision - auto LDRE = dyn_cast(L); - auto RDRE = dyn_cast(R); + auto* LDRE = dyn_cast(L); + auto* RDRE = dyn_cast(R); if (!LDRE && !RDRE) return Clone(BinOp); @@ -2414,7 +2484,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, return BuildOp(opCode, LExpr, RExpr); } Expr* op = BuildOp(opCode, Ldiff.getExpr(), Rdiff.getExpr()); - return StmtDiff(op, ResultRef); + return StmtDiff(op, ResultRef, nullptr, valueForRevPass); } VarDeclDiff ReverseModeVisitor::DifferentiateVarDecl(const VarDecl* VD) { @@ -2426,7 +2496,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // VDDerivedInit now serves two purposes -- as the initial derivative value // or the size of the derivative array -- depending on the primal type. - if (auto AT = dyn_cast(VD->getType())) { + if (const auto* AT = dyn_cast(VD->getType())) { Expr* init = getArraySizeExpr(AT, m_Context, *this); VDDerivedInit = init; VDDerived = BuildVarDecl(VDDerivedType, "_d_" + VD->getNameAsString(), @@ -2452,7 +2522,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // Computation of hessian requires this code to be correctly // differentiated. bool specialThisDiffCase = false; - if (auto MD = dyn_cast(m_Function)) { + if (const auto* MD = dyn_cast(m_Function)) { if (VDDerivedType->isPointerType() && MD->isInstance()) { specialThisDiffCase = true; } @@ -2533,13 +2603,14 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, VarDecl* VDClone = nullptr; // Here separate behaviour for record and non-record types is only // necessary to preserve the old tests. - if (VD->getType()->isRecordType()) - VDClone = BuildVarDecl(CloneType(VD->getType()), VD->getNameAsString(), + if (VD->getType()->isRecordType()) { + VDClone = BuildVarDecl(VD->getType(), VD->getNameAsString(), initDiff.getExpr(), VD->isDirectInit(), VD->getTypeSourceInfo(), VD->getInitStyle()); - else + } else { VDClone = BuildVarDecl(CloneType(VD->getType()), VD->getNameAsString(), initDiff.getExpr(), VD->isDirectInit()); + } Expr* derivedVDE = BuildDeclRef(VDDerived); // FIXME: Add extra parantheses if derived variable pointer is pointing to a @@ -2553,11 +2624,11 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, if (isInsideLoop) { auto tape = MakeCladTapeFor(derivedVDE); addToCurrentBlock(tape.Push); - auto reverseSweepDerivativePointerE = + auto* reverseSweepDerivativePointerE = BuildVarDecl(derivedVDE->getType(), "_t", tape.Pop); m_LoopBlock.back().push_back( BuildDeclStmt(reverseSweepDerivativePointerE)); - auto revSweepDerPointerRef = + auto* revSweepDerPointerRef = BuildDeclRef(reverseSweepDerivativePointerE); derivedVDE = BuildOp(UnaryOperatorKind::UO_Deref, revSweepDerPointerRef); @@ -2605,6 +2676,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } StmtDiff ReverseModeVisitor::VisitDeclStmt(const DeclStmt* DS) { + llvm::SmallVector inits; llvm::SmallVector decls; llvm::SmallVector declsDiff; // Need to put array decls inlined. @@ -2614,8 +2686,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // double y = x; // -> // double _d_y = _d_x; double y = x; - for (auto D : DS->decls()) { - if (auto VD = dyn_cast(D)) { + for (auto* D : DS->decls()) { + if (auto* VD = dyn_cast(D)) { VarDeclDiff VDDiff = DifferentiateVarDecl(VD); // Check if decl's name is the same as before. The name may be changed @@ -2638,6 +2710,28 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // } if (VDDiff.getDecl()->getDeclName() != VD->getDeclName()) m_DeclReplacements[VD] = VDDiff.getDecl(); + + /// FIXME: This part in necessary to replace local variables inside + /// loops with function globals and replace initializations with + /// assignments. This is a temporary measure to avoid the bug that + /// arises from overwriting local variables on different loop passes. + if (isInsideLoop) { + if (VD->getType()->isBuiltinType() && + !VD->getType().isConstQualified()) { + auto* decl = VDDiff.getDecl(); + if (decl->getInit()) { + auto* declRef = BuildDeclRef(decl); + auto pushPop = + StoreAndRestore(declRef, /*prefix=*/"_t", /*force=*/true); + if (pushPop.getExpr() != declRef) + addToCurrentBlock(pushPop.getExpr_dx(), direction::reverse); + auto* assignment = BuildOp(BO_Assign, declRef, decl->getInit()); + inits.push_back(BuildOp(BO_Comma, pushPop.getExpr(), assignment)); + } + decl->setInit(getZeroInit(VD->getType())); + } + } + decls.push_back(VDDiff.getDecl()); if (isa(VD->getType())) localDeclsDiff.push_back(VDDiff.getDecl_dx()); @@ -2667,21 +2761,36 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, declsDiff.append(localDeclsDiff.begin(), localDeclsDiff.end()); m_ExternalSource->ActBeforeFinalizingVisitDeclStmt(decls, declsDiff); } + + /// FIXME: This part in necessary to replace local variables inside loops + /// with function globals and replace initializations with assignments. + /// This is a temporary measure to avoid the bug that arises from + /// overwriting local variables on different loop passes. + if (isInsideLoop) { + if (auto* VD = dyn_cast(decls[0])) { + if (VD->getType()->isBuiltinType() && + !VD->getType().isConstQualified()) { + addToBlock(DSClone, m_Globals); + Stmt* initAssignments = MakeCompoundStmt(inits); + initAssignments = unwrapIfSingleStmt(initAssignments); + return StmtDiff(initAssignments); + } + } + } + return StmtDiff(DSClone); } StmtDiff ReverseModeVisitor::VisitImplicitCastExpr(const ImplicitCastExpr* ICE) { - StmtDiff subExprDiff = Visit(ICE->getSubExpr(), dfdx()); // Casts should be handled automatically when the result is used by // Sema::ActOn.../Build... - return StmtDiff(subExprDiff.getExpr(), subExprDiff.getExpr_dx(), - subExprDiff.getForwSweepStmt_dx()); + return Visit(ICE->getSubExpr(), dfdx()); } StmtDiff ReverseModeVisitor::VisitMemberExpr(const MemberExpr* ME) { auto baseDiff = VisitWithExplicitNoDfDx(ME->getBase()); - auto field = ME->getMemberDecl(); + auto* field = ME->getMemberDecl(); assert(!isa(field) && "CXXMethodDecl nodes not supported yet!"); MemberExpr* clonedME = utils::BuildMemberExpr( @@ -2707,27 +2816,41 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } bool ReverseModeVisitor::UsefulToStoreGlobal(Expr* E) { - if (isInsideLoop) - return !E->isEvaluatable(m_Context, Expr::SE_NoSideEffects); if (!E) return false; // Use stricter policy when inside loops: IsEvaluatable is also true for // arithmetical expressions consisting of constants, e.g. (1 + 2)*3. This // chech is more expensive, but it doesn't make sense to push such constants // into stack. - if (isInsideLoop) - return !E->isEvaluatable(m_Context, Expr::SE_NoSideEffects); + if (isInsideLoop && E->isEvaluatable(m_Context, Expr::SE_NoSideEffects)) + return false; Expr* B = E->IgnoreParenImpCasts(); // FIXME: find a more general way to determine that or add more options. if (isa(B) || isa(B)) return false; if (isa(B)) { - auto UO = cast(B); + auto* UO = cast(B); auto OpKind = UO->getOpcode(); if (OpKind == UO_Plus || OpKind == UO_Minus) return UsefulToStoreGlobal(UO->getSubExpr()); return true; } + // We lack context to decide if this is useful to store or not. In the + // current system that should have been decided by the parent expression. + // FIXME: Here will be the entry point of the advanced activity analysis. + if (isa(B) || isa(B) || + isa(B)) { + // If TBR analysis is off, assume E is useful to store. + if (!enableTBR) + return true; + auto found = m_ToBeRecorded.find(B->getBeginLoc()); + return found != m_ToBeRecorded.end(); + } + + // FIXME: Attach checkpointing. + if (isa(B)) + return false; + return true; } @@ -2736,7 +2859,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, Expr* init) { // Create identifier before going to topmost scope // to let Sema::LookupName see the whole scope. - auto identifier = CreateUniqueIdentifier(prefix); + auto* identifier = CreateUniqueIdentifier(prefix); // Save current scope and temporarily go to topmost function scope. llvm::SaveAndRestore SaveScope(m_CurScope); assert(m_DerivativeFnScope && "must be set"); @@ -2765,39 +2888,80 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, if (!force && !UsefulToStoreGlobal(E)) return {E, E}; + auto pushPop = BuildPushPop(E, Type, prefix, force); + if (!isInsideLoop) { + if (E) { + Expr* Set = BuildOp(BO_Assign, pushPop.getExpr(), E); + addToCurrentBlock(Set, direction::forward); + } + } + + return pushPop; + } + + StmtDiff ReverseModeVisitor::GlobalStoreAndRef(Expr* E, + llvm::StringRef prefix, + bool force) { + assert(E && "cannot infer type"); + return GlobalStoreAndRef( + E, getNonConstType(E->getType(), m_Context, m_Sema), prefix, force); + } + + StmtDiff ReverseModeVisitor::BuildPushPop(clang::Expr* E, + clang::QualType Type, + llvm::StringRef prefix, + bool force) { if (isInsideLoop) { - auto CladTape = MakeCladTapeFor(E); + auto CladTape = MakeCladTapeFor(Clone(E)); Expr* Push = CladTape.Push; Expr* Pop = CladTape.Pop; return {Push, Pop}; } - Expr* init = nullptr; - if (auto AT = dyn_cast(Type)) { + if (const auto* const AT = dyn_cast(Type)) init = getArraySizeExpr(AT, m_Context, *this); - } Expr* Ref = BuildDeclRef(GlobalStoreImpl(Type, prefix, init)); - if (E) { - Expr* Set = BuildOp(BO_Assign, Ref, E); - addToCurrentBlock(Set, direction::forward); - } return {Ref, Ref}; } - StmtDiff ReverseModeVisitor::GlobalStoreAndRef(Expr* E, - llvm::StringRef prefix, - bool force) { - assert(E && "cannot infer type"); - return GlobalStoreAndRef( - E, getNonConstType(E->getType(), m_Context, m_Sema), prefix, force); + StmtDiff ReverseModeVisitor::StoreAndRestore(clang::Expr* E, + llvm::StringRef prefix, + bool force) { + auto Type = getNonConstType(E->getType(), m_Context, m_Sema); + + if (!force && !UsefulToStoreGlobal(E)) + return {}; + + if (isInsideLoop) { + auto pushPop = BuildPushPop(E, Type, prefix, true); + auto* popAssign = BuildOp(BinaryOperatorKind::BO_Assign, Clone(E), + pushPop.getExpr_dx()); + return {pushPop.getExpr(), popAssign}; + } + + Expr* init = nullptr; + if (const auto* AT = dyn_cast(Type)) + init = getArraySizeExpr(AT, m_Context, *this); + + Expr* Ref = BuildDeclRef(GlobalStoreImpl(Type, prefix, init)); + if (E) { + Expr* Store = BuildOp(BO_Assign, Ref, Clone(E)); + Expr* Restore = nullptr; + if (E->isModifiableLvalue(m_Context) == Expr::MLV_Valid) { + auto* r = Clone(E); + Restore = BuildOp(BO_Assign, r, Ref); + } + return {Store, Restore}; + } + return {}; } void ReverseModeVisitor::DelayedStoreResult::Finalize(Expr* New) { - if (isConstant) + if (isConstant || !needsUpdate) return; if (isInsideLoop) { - auto Push = cast(Result.getExpr()); + auto* Push = cast(Result.getExpr()); unsigned lastArg = Push->getNumArgs() - 1; Push->setArg(lastArg, V.m_Sema.DefaultLvalueConversion(New).get()); } else { @@ -2810,39 +2974,39 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, ReverseModeVisitor::DelayedGlobalStoreAndRef(Expr* E, llvm::StringRef prefix) { assert(E && "must be provided"); - if (!UsefulToStoreGlobal(E)) { + if (isa(E) /*!UsefulToStoreGlobal(E)*/) { Expr* Cloned = Clone(E); - return DelayedStoreResult{*this, - StmtDiff{Cloned, Cloned}, - /*isConstant*/ true, - /*isInsideLoop*/ false}; + Expr::EvalResult evalRes; + bool isConst = + clad_compat::Expr_EvaluateAsConstantExpr(E, evalRes, m_Context); + return DelayedStoreResult{*this, StmtDiff{Cloned, Cloned}, + /*isConstant*/ isConst, + /*isInsideLoop*/ false, + /*pNeedsUpdate=*/false}; } if (isInsideLoop) { Expr* dummy = E; auto CladTape = MakeCladTapeFor(dummy); Expr* Push = CladTape.Push; Expr* Pop = CladTape.Pop; - return DelayedStoreResult{*this, - StmtDiff{Push, Pop}, - /*isConstant*/ false, - /*isInsideLoop*/ true}; - } else { - Expr* Ref = BuildDeclRef(GlobalStoreImpl( - getNonConstType(E->getType(), m_Context, m_Sema), prefix)); - // Return reference to the declaration instead of original expression. - return DelayedStoreResult{*this, - StmtDiff{Ref, Ref}, + return DelayedStoreResult{*this, StmtDiff{Push, Pop, nullptr, Pop}, /*isConstant*/ false, - /*isInsideLoop*/ false}; - } + /*isInsideLoop*/ true, /*pNeedsUpdate=*/true}; + } + Expr* Ref = BuildDeclRef(GlobalStoreImpl( + getNonConstType(E->getType(), m_Context, m_Sema), prefix)); + // Return reference to the declaration instead of original expression. + return DelayedStoreResult{*this, StmtDiff{Ref, Ref}, + /*isConstant*/ false, + /*isInsideLoop*/ false, /*pNeedsUpdate=*/true}; } ReverseModeVisitor::LoopCounter::LoopCounter(ReverseModeVisitor& RMV) : m_RMV(RMV) { ASTContext& C = m_RMV.m_Context; if (RMV.isInsideLoop) { - auto zero = ConstantFolder::synthesizeLiteral(C.getSizeType(), C, - /*val=*/0); + auto* zero = ConstantFolder::synthesizeLiteral(C.getSizeType(), C, + /*val=*/0); auto counterTape = m_RMV.MakeCladTapeFor(zero); m_Ref = counterTape.Last(); m_Pop = counterTape.Pop; @@ -2878,10 +3042,18 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // statement. Sema::ConditionResult condResult; if (condVarDecl) { - Decl* condVarClone = cast(condVarRes.getStmt()) - ->getSingleDecl(); - condResult = m_Sema.ActOnConditionVariable(condVarClone, noLoc, - Sema::ConditionKind::Boolean); + if (condVarRes.getStmt()) { + if (isa(condVarRes.getStmt())) { + Decl* condVarClone = + cast(condVarRes.getStmt())->getSingleDecl(); + condResult = m_Sema.ActOnConditionVariable( + condVarClone, noLoc, Sema::ConditionKind::Boolean); + } else { + condResult = m_Sema.ActOnCondition(getCurrentScope(), noLoc, + cast(condVarRes.getStmt()), + Sema::ConditionKind::Boolean); + } + } } else { condResult = m_Sema.ActOnCondition(getCurrentScope(), noLoc, condClone, Sema::ConditionKind::Boolean); @@ -2955,7 +3127,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, .ActOnDoStmt(/*DoLoc=*/noLoc, bodyDiff.getStmt_dx(), /*WhileLoc=*/noLoc, /*CondLParen=*/noLoc, counterCondition, - /*RCondRParen=*/noLoc) + /*CondRParen=*/noLoc) .get(); // for do-while statement endScope(); @@ -2986,9 +3158,9 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, Stmt* forLoopIncDiff, bool isForLoop) { Expr* counterIncrement = loopCounter.getCounterIncrement(); - auto activeBreakContHandler = PushBreakContStmtHandler(); + auto* activeBreakContHandler = PushBreakContStmtHandler(); activeBreakContHandler->BeginCFSwitchStmtScope(); - m_LoopBlock.push_back({}); + m_LoopBlock.emplace_back(); // differentiate loop body and add loop increment expression // in the forward block. StmtDiff bodyDiff = nullptr; @@ -3022,6 +3194,18 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, bodyDiff.updateStmtDx(MakeCompoundStmt(revLoopBlock)); m_LoopBlock.pop_back(); + /// Increment statement in the for-loop is only executed if the iteration + /// did not end with a break/continue statement. Therefore, forLoopIncDiff + /// should be inside the last switch case in the reverse pass. + if (forLoopIncDiff) { + if (bodyDiff.getStmt_dx()) { + bodyDiff.updateStmtDx(utils::PrependAndCreateCompoundStmt( + m_Context, bodyDiff.getStmt_dx(), forLoopIncDiff)); + } else { + bodyDiff.updateStmtDx(forLoopIncDiff); + } + } + activeBreakContHandler->EndCFSwitchStmtScope(); activeBreakContHandler->UpdateForwAndRevBlocks(bodyDiff); PopBreakContStmtHandler(); @@ -3043,7 +3227,6 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, addToCurrentBlock(counterDecrement, direction::reverse); addToCurrentBlock(condVarDiff, direction::reverse); addToCurrentBlock(bodyDiff.getStmt_dx(), direction::reverse); - addToCurrentBlock(forLoopIncDiff, direction::reverse); bodyDiff = {bodyDiff.getStmt(), unwrapIfSingleStmt(endBlock(direction::reverse))}; return bodyDiff; @@ -3052,7 +3235,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, StmtDiff ReverseModeVisitor::VisitContinueStmt(const ContinueStmt* CS) { beginBlock(direction::forward); Stmt* newCS = m_Sema.ActOnContinueStmt(noLoc, getCurrentScope()).get(); - auto activeBreakContHandler = GetActiveBreakContStmtHandler(); + auto* activeBreakContHandler = GetActiveBreakContStmtHandler(); Stmt* CFCaseStmt = activeBreakContHandler->GetNextCFCaseStmt(); Stmt* pushExprToCurrentCase = activeBreakContHandler ->CreateCFTapePushExprToCurrentCase(); @@ -3064,7 +3247,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, StmtDiff ReverseModeVisitor::VisitBreakStmt(const BreakStmt* BS) { beginBlock(direction::forward); Stmt* newBS = m_Sema.ActOnBreakStmt(noLoc, getCurrentScope()).get(); - auto activeBreakContHandler = GetActiveBreakContStmtHandler(); + auto* activeBreakContHandler = GetActiveBreakContStmtHandler(); Stmt* CFCaseStmt = activeBreakContHandler->GetNextCFCaseStmt(); Stmt* pushExprToCurrentCase = activeBreakContHandler ->CreateCFTapePushExprToCurrentCase(); @@ -3076,8 +3259,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, Expr* ReverseModeVisitor::BreakContStmtHandler::CreateSizeTLiteralExpr( std::size_t value) { ASTContext& C = m_RMV.m_Context; - auto literalExpr = ConstantFolder::synthesizeLiteral(C.getSizeType(), C, - value); + auto* literalExpr = + ConstantFolder::synthesizeLiteral(C.getSizeType(), C, value); return literalExpr; } @@ -3085,7 +3268,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, assert(!m_ControlFlowTape && "InitializeCFTape() should not be called if " "m_ControlFlowTape is already initialized"); - auto zeroLiteral = CreateSizeTLiteralExpr(0); + auto* zeroLiteral = CreateSizeTLiteralExpr(0); m_ControlFlowTape.reset( new CladTapeResult(m_RMV.MakeCladTapeFor(zeroLiteral))); } @@ -3117,7 +3300,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, m_RMV.endScope(); ++m_CaseCounter; - auto counterLiteral = CreateSizeTLiteralExpr(m_CaseCounter); + auto* counterLiteral = CreateSizeTLiteralExpr(m_CaseCounter); CaseStmt* CS = clad_compat::CaseStmt_Create(m_RMV.m_Context, counterLiteral, nullptr, noLoc, noLoc, noLoc); @@ -3154,10 +3337,11 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // and corresponding push expression for this case statement // at the end of the forward block to cover the case when no // `break`/`continue` statements are hit. - auto lastSC = GetNextCFCaseStmt(); - auto pushExprToCurrentCase = CreateCFTapePushExprToCurrentCase(); + auto* lastSC = GetNextCFCaseStmt(); + auto* pushExprToCurrentCase = CreateCFTapePushExprToCurrentCase(); - Stmt *forwBlock, *revBlock; + Stmt* forwBlock = nullptr; + Stmt* revBlock = nullptr; forwBlock = utils::AppendAndCreateCompoundStmt(m_RMV.m_Context, bodyDiff.getStmt(), @@ -3171,14 +3355,12 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, auto condResult = m_RMV.m_Sema.ActOnCondition(m_RMV.getCurrentScope(), noLoc, m_ControlFlowTape->Pop, Sema::ConditionKind::Switch); - SwitchStmt* CFSS = clad_compat::Sema_ActOnStartOfSwitchStmt(m_RMV.m_Sema, - nullptr, - condResult) - .getAs(); + auto* CFSS = clad_compat::Sema_ActOnStartOfSwitchStmt(m_RMV.m_Sema, nullptr, + condResult) + .getAs(); // Registers all the switch cases - for (auto SC : m_SwitchCases) { + for (auto* SC : m_SwitchCases) CFSS->addSwitchCase(SC); - } m_RMV.m_Sema.ActOnFinishSwitchStmt(noLoc, CFSS, bodyDiff.getStmt_dx()); bodyDiff = {bodyDiff.getStmt(), CFSS}; @@ -3201,7 +3383,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, StmtDiff ReverseModeVisitor::VisitCXXConstructExpr(const CXXConstructExpr* CE) { llvm::SmallVector clonedArgs; - for (auto arg : CE->arguments()) { + for (const auto* arg : CE->arguments()) { auto argDiff = Visit(arg, dfdx()); clonedArgs.push_back(argDiff.getExpr()); } @@ -3216,10 +3398,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, // Passing empty parenList here will silently cause 'most vexing // parse' issue. return StmtDiff(); - } else { - clonedArgsE = - m_Sema.ActOnParenListExpr(noLoc, noLoc, clonedArgs).get(); } + clonedArgsE = m_Sema.ActOnParenListExpr(noLoc, noLoc, clonedArgs).get(); } } else { clonedArgsE = clonedArgs[0]; @@ -3281,9 +3461,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, ReverseModeVisitor::ComputeParamTypes(const DiffParams& diffParams) { llvm::SmallVector paramTypes; paramTypes.reserve(m_Function->getNumParams() * 2); - for (auto PVD : m_Function->parameters()) { + for (auto* PVD : m_Function->parameters()) paramTypes.push_back(PVD->getType()); - } // TODO: Add DiffMode::experimental_pullback support here as well. if (m_Mode == DiffMode::reverse || m_Mode == DiffMode::experimental_pullback) { @@ -3305,7 +3484,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, paramTypes.push_back(effectiveReturnType); } - if (auto MD = dyn_cast(m_Function)) { + if (const auto* MD = dyn_cast(m_Function)) { const CXXRecordDecl* RD = MD->getParent(); if (MD->isInstance() && !RD->isLambda()) { QualType thisType = @@ -3315,8 +3494,9 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } } - for (auto PVD : m_Function->parameters()) { - auto it = std::find(std::begin(diffParams), std::end(diffParams), PVD); + for (auto* PVD : m_Function->parameters()) { + const auto* it = + std::find(std::begin(diffParams), std::end(diffParams), PVD); if (it != std::end(diffParams)) paramTypes.push_back(ComputeParamType(PVD->getType())); } @@ -3331,9 +3511,11 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, llvm::SmallVector ReverseModeVisitor::BuildParams(DiffParams& diffParams) { - llvm::SmallVector params, paramDerivatives; + llvm::SmallVector params; + llvm::SmallVector paramDerivatives; params.reserve(m_Function->getNumParams() + diffParams.size()); - auto derivativeFnType = cast(m_Derivative->getType()); + const auto* derivativeFnType = + cast(m_Derivative->getType()); std::size_t dParamTypesIdx = m_Function->getNumParams(); if (m_Mode == DiffMode::experimental_pullback && @@ -3341,10 +3523,10 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, ++dParamTypesIdx; } - if (auto MD = dyn_cast(m_Function)) { + if (const auto* MD = dyn_cast(m_Function)) { const CXXRecordDecl* RD = MD->getParent(); if (!isVectorValued && MD->isInstance() && !RD->isLambda()) { - auto thisDerivativePVD = utils::BuildParmVarDecl( + auto* thisDerivativePVD = utils::BuildParmVarDecl( m_Sema, m_Derivative, CreateUniqueIdentifier("_d_this"), derivativeFnType->getParamType(dParamTypesIdx)); paramDerivatives.push_back(thisDerivativePVD); @@ -3362,8 +3544,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, } } - for (auto PVD : m_Function->parameters()) { - auto newPVD = utils::BuildParmVarDecl( + for (auto* PVD : m_Function->parameters()) { + auto* newPVD = utils::BuildParmVarDecl( m_Sema, m_Derivative, PVD->getIdentifier(), PVD->getType(), PVD->getStorageClass(), /*DefArg=*/nullptr, PVD->getTypeSourceInfo()); params.push_back(newPVD); @@ -3372,7 +3554,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, m_Sema.PushOnScopeChains(newPVD, getCurrentScope(), /*AddToContext=*/false); - auto it = std::find(std::begin(diffParams), std::end(diffParams), PVD); + auto* it = std::find(std::begin(diffParams), std::end(diffParams), PVD); if (it != std::end(diffParams)) { *it = newPVD; if (m_Mode == DiffMode::reverse || @@ -3380,8 +3562,8 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, QualType dType = derivativeFnType->getParamType(dParamTypesIdx); IdentifierInfo* dII = CreateUniqueIdentifier("_d_" + PVD->getNameAsString()); - auto dPVD = utils::BuildParmVarDecl(m_Sema, m_Derivative, dII, dType, - PVD->getStorageClass()); + auto* dPVD = utils::BuildParmVarDecl(m_Sema, m_Derivative, dII, dType, + PVD->getStorageClass()); paramDerivatives.push_back(dPVD); ++dParamTypesIdx; @@ -3426,7 +3608,7 @@ Expr* getArraySizeExpr(const ArrayType* AT, ASTContext& context, if (m_Mode == DiffMode::jacobian) { IdentifierInfo* II = CreateUniqueIdentifier("jacobianMatrix"); // FIXME: Why are we taking storageClass of `params.front()`? - auto dPVD = utils::BuildParmVarDecl( + auto* dPVD = utils::BuildParmVarDecl( m_Sema, m_Derivative, II, derivativeFnType->getParamType(dParamTypesIdx), params.front()->getStorageClass()); diff --git a/lib/Differentiator/StmtClone.cpp b/lib/Differentiator/StmtClone.cpp index e14c7fa78..4d9db2464 100644 --- a/lib/Differentiator/StmtClone.cpp +++ b/lib/Differentiator/StmtClone.cpp @@ -501,9 +501,12 @@ Stmt* StmtClone::VisitStmt(Stmt*) { return 0; } -ReferencesUpdater::ReferencesUpdater(Sema& SemaRef, Scope* S, - const FunctionDecl* FD) - : m_Sema(SemaRef), m_CurScope(S), m_Function(FD) {} +ReferencesUpdater::ReferencesUpdater( + Sema& SemaRef, Scope* S, const FunctionDecl* FD, + const std::unordered_map& + DeclReplacements) + : m_Sema(SemaRef), m_CurScope(S), m_Function(FD), + m_DeclReplacements(DeclReplacements) {} bool ReferencesUpdater::VisitDeclRefExpr(DeclRefExpr* DRE) { // We should only update references of the declarations that were inside @@ -511,6 +514,14 @@ bool ReferencesUpdater::VisitDeclRefExpr(DeclRefExpr* DRE) { // Original function = function that we are currently differentiating. if (!DRE->getDecl()->getDeclContext()->Encloses(m_Function)) return true; + + // Replace the declaration if it is present in `m_DeclReplacements`. + if (VarDecl* VD = dyn_cast(DRE->getDecl())) { + auto it = m_DeclReplacements.find(VD); + if (it != std::end(m_DeclReplacements)) + DRE->setDecl(it->second); + } + DeclarationNameInfo DNI = DRE->getNameInfo(); LookupResult R(m_Sema, DNI, Sema::LookupOrdinaryName); diff --git a/lib/Differentiator/TBRAnalyzer.cpp b/lib/Differentiator/TBRAnalyzer.cpp new file mode 100644 index 000000000..21b74a9d8 --- /dev/null +++ b/lib/Differentiator/TBRAnalyzer.cpp @@ -0,0 +1,824 @@ +#include "TBRAnalyzer.h" + +#include "llvm/Support/Debug.h" +#undef DEBUG_TYPE +#define DEBUG_TYPE "clad-tbr" + +using namespace clang; + +namespace clad { + +// NOLINTBEGIN(cppcoreguidelines-pro-type-union-access) +void TBRAnalyzer::setIsRequired(VarData& varData, bool isReq) { + if (varData.m_Type == VarData::FUND_TYPE) + varData.m_Val.m_FundData = isReq; + else if (varData.m_Type == VarData::OBJ_TYPE || + varData.m_Type == VarData::ARR_TYPE) + for (auto& pair : *varData.m_Val.m_ArrData) + setIsRequired(pair.second, isReq); + else if (varData.m_Type == VarData::REF_TYPE && varData.m_Val.m_RefData) + if (auto* data = getExprVarData(varData.m_Val.m_RefData)) + setIsRequired(*data, isReq); +} + +void TBRAnalyzer::merge(VarData& targetData, VarData& mergeData) { + if (targetData.m_Type == VarData::FUND_TYPE) { + targetData.m_Val.m_FundData = + targetData.m_Val.m_FundData || mergeData.m_Val.m_FundData; + } else if (targetData.m_Type == VarData::OBJ_TYPE) { + for (auto& pair : *targetData.m_Val.m_ArrData) + merge(pair.second, (*mergeData.m_Val.m_ArrData)[pair.first]); + } else if (targetData.m_Type == VarData::ARR_TYPE) { + // FIXME: Currently non-constant indices are not supported in merging. + for (auto& pair : *targetData.m_Val.m_ArrData) { + auto it = mergeData.m_Val.m_ArrData->find(pair.first); + if (it != mergeData.m_Val.m_ArrData->end()) + merge(pair.second, it->second); + } + for (auto& pair : *mergeData.m_Val.m_ArrData) { + auto it = targetData.m_Val.m_ArrData->find(pair.first); + if (it == mergeData.m_Val.m_ArrData->end()) + (*targetData.m_Val.m_ArrData)[pair.first] = copy(pair.second); + } + } + // This might be useful in future if used to analyse pointers. However, for + // now it's only used for references for which merging doesn't make sense. + // else if (this.m_Type == VarData::REF_TYPE) {} +} + +TBRAnalyzer::VarData TBRAnalyzer::copy(VarData& copyData) { + VarData res; + res.m_Type = copyData.m_Type; + if (copyData.m_Type == VarData::FUND_TYPE) { + res.m_Val.m_FundData = copyData.m_Val.m_FundData; + } else if (copyData.m_Type == VarData::OBJ_TYPE || + copyData.m_Type == VarData::ARR_TYPE) { + res.m_Val.m_ArrData = std::unique_ptr(new ArrMap()); + for (auto& pair : *copyData.m_Val.m_ArrData) + (*res.m_Val.m_ArrData)[pair.first] = copy(pair.second); + } else if (copyData.m_Type == VarData::REF_TYPE && copyData.m_Val.m_RefData) { + res.m_Val.m_RefData = copyData.m_Val.m_RefData; + } + return res; +} + +bool TBRAnalyzer::findReq(const VarData& varData) { + if (varData.m_Type == VarData::FUND_TYPE) + return varData.m_Val.m_FundData; + if (varData.m_Type == VarData::OBJ_TYPE || + varData.m_Type == VarData::ARR_TYPE) { + for (auto& pair : *varData.m_Val.m_ArrData) + if (findReq(pair.second)) + return true; + } else if (varData.m_Type == VarData::REF_TYPE && varData.m_Val.m_RefData) { + if (auto* data = getExprVarData(varData.m_Val.m_RefData)) { + if (findReq(*data)) + return true; + } + } + return false; +} + +void TBRAnalyzer::overlay(VarData& targetData, + llvm::SmallVector& IDSequence, + size_t i) { + if (i == 0) { + setIsRequired(targetData); + return; + } + --i; + ProfileID& curID = IDSequence[i]; + // non-constant indices are represented with default ID. + ProfileID nonConstIdxID; + if (curID == nonConstIdxID) + for (auto& pair : *targetData.m_Val.m_ArrData) + overlay(pair.second, IDSequence, i); + else + overlay((*targetData.m_Val.m_ArrData)[curID], IDSequence, i); +} + +TBRAnalyzer::VarData* TBRAnalyzer::getMemberVarData(const clang::MemberExpr* ME, + bool addNonConstIdx) { + if (const auto* FD = dyn_cast(ME->getMemberDecl())) { + const auto* base = ME->getBase(); + VarData* baseData = getExprVarData(base); + + if (!baseData) + return nullptr; + + // if non-const index was found and it is not supposed to be added just + // return the current VarData*. + if (m_NonConstIndexFound && !addNonConstIdx) + return baseData; + + return &(*baseData->m_Val.m_ArrData)[getProfileID(FD)]; + } + return nullptr; +} + +TBRAnalyzer::VarData* +TBRAnalyzer::getArrSubVarData(const clang::ArraySubscriptExpr* ASE, + bool addNonConstIdx) { + const auto* idxExpr = ASE->getIdx(); + ProfileID idxID; + if (const auto* IL = dyn_cast(idxExpr)) { + idxID = getProfileID(IL); + } else { + m_NonConstIndexFound = true; + // Non-const indices are represented with default FoldingSetNodeID. + } + + const auto* base = ASE->getBase()->IgnoreImpCasts(); + VarData* baseData = getExprVarData(base); + + if (!baseData) + return nullptr; + + // if non-const index was found and it is not supposed to be added just + // return the current VarData*. + if (m_NonConstIndexFound && !addNonConstIdx) + return baseData; + + auto* baseArrMap = baseData->m_Val.m_ArrData.get(); + auto it = baseArrMap->find(idxID); + + // Add the current index if it was not added previously + if (it == baseArrMap->end()) { + auto& idxData = (*baseArrMap)[idxID]; + // Since default ID represents non-const indices, whenever we add a new + // index we have to copy the VarData of default ID's element (if an element + // with undefined index was used this might be our current element). + ProfileID nonConstIdxID; + idxData = copy((*baseArrMap)[nonConstIdxID]); + return &idxData; + } + + return &it->second; +} + +TBRAnalyzer::VarData* TBRAnalyzer::getExprVarData(const clang::Expr* E, + bool addNonConstIdx) { + // This line is necessary for pointer member expressions (in 'x->y' x would be + // implicitly casted with the * operator). + E = E->IgnoreImpCasts(); + VarData* EData = nullptr; + if (isa(E) || isa(E)) { + const VarDecl* VD = nullptr; + // ``this`` does not have a declaration so it is represented with nullptr. + if (const auto* DRE = dyn_cast(E)) + VD = dyn_cast(DRE->getDecl()); + auto* branch = &getCurBlockVarsData(); + while (branch) { + auto it = branch->find(VD); + if (it != branch->end()) { + EData = &it->second; + break; + } + branch = branch->m_Prev; + } + } + if (const auto* ME = dyn_cast(E)) + EData = getMemberVarData(ME, addNonConstIdx); + if (const auto* ASE = dyn_cast(E)) + EData = getArrSubVarData(ASE, addNonConstIdx); + + if (EData && EData->m_Type == VarData::REF_TYPE && EData->m_Val.m_RefData) + EData = getExprVarData(EData->m_Val.m_RefData); + + return EData; +} + +TBRAnalyzer::VarData::VarData(const QualType QT) { + if (QT->isReferenceType()) { + m_Type = VarData::REF_TYPE; + m_Val.m_RefData = nullptr; + } else if (utils::isArrayOrPointerType(QT)) { + m_Type = VarData::ARR_TYPE; + m_Val.m_ArrData = std::unique_ptr(new ArrMap()); + const Type* elemType = nullptr; + if (const auto* const pointerType = llvm::dyn_cast(QT)) + elemType = pointerType->getPointeeType().getTypePtrOrNull(); + else + elemType = QT->getArrayElementTypeNoTypeQual(); + ProfileID nonConstIdxID; + auto& idxData = (*m_Val.m_ArrData)[nonConstIdxID]; + idxData = VarData(QualType::getFromOpaquePtr(elemType)); + } else if (QT->isBuiltinType()) { + m_Type = VarData::FUND_TYPE; + m_Val.m_FundData = false; + } else if (const auto* recordType = QT->getAs()) { + m_Type = VarData::OBJ_TYPE; + const auto* recordDecl = recordType->getDecl(); + auto& newArrMap = m_Val.m_ArrData; + newArrMap = std::unique_ptr(new ArrMap()); + for (const auto* field : recordDecl->fields()) { + const auto varType = field->getType(); + (*newArrMap)[getProfileID(field)] = VarData(varType); + } + } +} + +void TBRAnalyzer::overlay(const clang::Expr* E) { + m_NonConstIndexFound = false; + llvm::SmallVector IDSequence; + const clang::DeclRefExpr* innermostDRE = nullptr; + bool cond = true; + // Unwrap the given expression to a vector of indices and fields. + while (cond) { + E = E->IgnoreImplicit(); + if (const auto* ASE = dyn_cast(E)) { + if (const auto* IL = dyn_cast(ASE->getIdx())) + IDSequence.push_back(getProfileID(IL)); + else + IDSequence.push_back(ProfileID()); + E = ASE->getBase(); + } else if (const auto* ME = dyn_cast(E)) { + if (const auto* FD = dyn_cast(ME->getMemberDecl())) + IDSequence.push_back(getProfileID(FD)); + E = ME->getBase(); + } else if (isa(E)) { + innermostDRE = dyn_cast(E); + cond = false; + } else + return; + } + + // Overlay on all the VarData's recursively. + if (const auto* VD = dyn_cast(innermostDRE->getDecl())) + overlay(getCurBlockVarsData()[VD], IDSequence, IDSequence.size()); +} +// NOLINTEND(cppcoreguidelines-pro-type-union-access) + +void TBRAnalyzer::copyVarToCurBlock(const clang::VarDecl* VD) { + // Visit all predecessors one by one until the variable VD is found. + auto& curBranch = getCurBlockVarsData(); + auto* pred = curBranch.m_Prev; + while (pred) { + auto it = pred->find(VD); + if (it != pred->end()) { + curBranch[VD] = copy(it->second); + return; + } + pred = pred->m_Prev; + } + // If this variable was not found in predecessors, add it. + addVar(VD); +} + +void TBRAnalyzer::addVar(const clang::VarDecl* VD) { + auto& curBranch = getCurBlockVarsData(); + + QualType varType; + if (const auto* arrayParam = dyn_cast(VD)) + varType = arrayParam->getOriginalType(); + else + varType = VD->getType(); + // If varType represents auto or auto*, get the type of init. + if (utils::IsAutoOrAutoPtrType(varType)) + varType = VD->getInit()->getType(); + + // FIXME: If the pointer points to an object we represent it with a OBJ_TYPE + // VarData. This is done for '_d_this' pointer to be processed correctly in + // hessian mode. This should be removed once full support for pointers in + // analysis is introduced. + if (const auto* const pointerType = dyn_cast(varType)) { + const auto* elemType = pointerType->getPointeeType().getTypePtrOrNull(); + if (elemType && elemType->isRecordType()) { + curBranch[VD] = VarData(QualType::getFromOpaquePtr(elemType)); + return; + } + } + curBranch[VD] = VarData(varType); +} + +void TBRAnalyzer::markLocation(const clang::Expr* E) { + VarData* data = getExprVarData(E); + if (!data || findReq(*data)) { + // FIXME: If any of the data's child nodes are required to store then data + // itself is stored. We might add an option to store separate fields. + // FIXME: Sometimes one location might correspond to multiple stores. For + // example, in ``(x*=y)=u`` x's location will first be marked as required to + // be stored (when passing *= operator) but then marked as not required to + // be stored (when passing = operator). Current method of marking locations + // does not allow to differentiate between these two. + m_TBRLocs.insert(E->getBeginLoc()); + } +} + +void TBRAnalyzer::setIsRequired(const clang::Expr* E, bool isReq) { + if (!isReq || + (m_ModeStack.back() == (Mode::kMarkingMode | Mode::kNonLinearMode))) { + VarData* data = getExprVarData(E, /*addNonConstIdx=*/isReq); + if (data && (isReq || !m_NonConstIndexFound)) + setIsRequired(*data, isReq); + // If an array element with a non-const element is set to required all the + // elements of that array should be set to required. + if (isReq && m_NonConstIndexFound) + overlay(E); + m_NonConstIndexFound = false; + } +} + +void TBRAnalyzer::Analyze(const FunctionDecl* FD) { + // Build the CFG (control-flow graph) of FD. + clang::CFG::BuildOptions Options; + m_CFG = clang::CFG::buildCFG(FD, FD->getBody(), &m_Context, Options); + + m_BlockData.resize(m_CFG->size()); + m_BlockPassCounter.resize(m_CFG->size(), 0); + + // Set current block ID to the ID of entry the block. + auto* entry = &m_CFG->getEntry(); + m_CurBlockID = entry->getBlockID(); + m_BlockData[m_CurBlockID] = std::unique_ptr(new VarsData()); + + // If we are analysing a non-static method, add a VarData for 'this' pointer + // (it is represented with nullptr). + const auto* MD = dyn_cast(FD); + if (MD && !MD->isStatic()) { + const Type* recordType = MD->getParent()->getTypeForDecl(); + getCurBlockVarsData()[nullptr] = + VarData(QualType::getFromOpaquePtr(recordType)); + } + auto paramsRef = FD->parameters(); + for (std::size_t i = 0; i < FD->getNumParams(); ++i) + addVar(paramsRef[i]); + // Add the entry block to the queue. + m_CFGQueue.insert(m_CurBlockID); + + // Visit CFG blocks in the queue until it's empty. + while (!m_CFGQueue.empty()) { + auto IDIter = std::prev(m_CFGQueue.end()); + m_CurBlockID = *IDIter; + m_CFGQueue.erase(IDIter); + + CFGBlock& nextBlock = *getCFGBlockByID(m_CurBlockID); + VisitCFGBlock(nextBlock); + } +#ifndef NDEBUG + for (int id = m_CurBlockID; id >= 0; --id) { + LLVM_DEBUG(llvm::dbgs() << "\n-----BLOCK" << id << "-----\n\n"); + for (auto succ : getCFGBlockByID(id)->succs()) + if (succ) + LLVM_DEBUG(llvm::dbgs() << "successor: " << succ->getBlockID() << "\n"); + } +#endif // NDEBUG +} + +void TBRAnalyzer::VisitCFGBlock(const CFGBlock& block) { + LLVM_DEBUG(llvm::dbgs() << "Entering block " << block.getBlockID() << "\n"); + // Visiting loop blocks just once is not enough since the end of one loop + // iteration may have an effect on the next one. However, two iterations is + // always enough. Allow a third visit without going to successors to correctly + // analyse loop conditions. + bool notLastPass = ++m_BlockPassCounter[block.getBlockID()] <= 2; + + // Visit all the statements inside the block. + for (const clang::CFGElement& Element : block) { + if (Element.getKind() == clang::CFGElement::Statement) { + const clang::Stmt* S = Element.castAs().getStmt(); + TraverseStmt(const_cast(S)); + } + } + + // Traverse successor CFG blocks. + for (const auto succ : block.succs()) { + // Sometimes clang CFG does not create blocks for parts of code that + // are never executed (e.g. 'if (0) {...'). Add this check for safety. + if (!succ) + continue; + auto& varsData = m_BlockData[succ->getBlockID()]; + + // Create VarsData for the succ branch if it hasn't been done previously. + // If the successor doesn't have a VarsData, assign it and attach the + // current block as previous. + if (!varsData) { + varsData = std::unique_ptr(new VarsData()); + varsData->m_Prev = m_BlockData[block.getBlockID()].get(); + } + + // If this is the third (last) pass of block, it means block represents a + // loop condition and the loop body has already been visited 2 times. This + // means we should not visit the loop body anymore. + if (notLastPass) { + // Add the successor to the queue. + m_CFGQueue.insert(succ->getBlockID()); + + // This part is necessary for loops. For other cases, this is not supposed + // to do anything. + if (succ->getBlockID() < block.getBlockID()) { + // If there is another loop condition present inside a loop, + // We have to set it's loop pass counter to 0 (it might be 3 + // from the previous outer loop pass). + m_BlockPassCounter[succ->getBlockID()] = 0; + // Remove VarsData left after the previous pass. + varsData->clear(); + } + } + + // If the successor's previous block is not this one, perform a merge. + if (varsData->m_Prev != m_BlockData[block.getBlockID()].get()) + merge(varsData.get(), m_BlockData[block.getBlockID()].get()); + } + LLVM_DEBUG(llvm::dbgs() << "Leaving block " << block.getBlockID() << "\n"); +} + +CFGBlock* TBRAnalyzer::getCFGBlockByID(unsigned ID) { + return *(m_CFG->begin() + ID); +} + +TBRAnalyzer::VarsData* +TBRAnalyzer::findLowestCommonAncestor(VarsData* varsData1, + VarsData* varsData2) { + VarsData* pred1 = varsData1; + VarsData* pred2 = varsData2; + while (true) { + if (pred1 == pred2) + return pred1; + + auto* branch = varsData1; + while (branch != pred1) { + if (branch == pred2) + return branch; + branch = branch->m_Prev; + } + + branch = varsData2; + while (branch != pred2) { + if (branch == pred1) + return branch; + branch = branch->m_Prev; + } + + if (pred1->m_Prev) { + pred1 = pred1->m_Prev; + // This ensures we don't get an infinite loop because of VarsData being + // connected in a loop themselves. + if (pred1 == varsData1) + return nullptr; + } else { + // pred1 not having a predecessor means it is corresponds to the entry + // block and, therefore it is the lowest common ancestor. + return pred1; + } + + if (pred2->m_Prev) { + pred2 = pred2->m_Prev; + // This ensures we don't get an infinite loop because of VarsData being + // connected in a loop themselves. + if (pred2 == varsData2) + return nullptr; + } else { + // pred2 not having a predecessor means it is corresponds to the entry + // block and, therefore it is the lowest common ancestor. + return pred2; + } + } +} + +std::unordered_map +TBRAnalyzer::collectDataFromPredecessors(VarsData* varsData, + TBRAnalyzer::VarsData* limit) { + std::unordered_map result; + if (varsData != limit) { + // Copy data from every predecessor. + for (auto* pred = varsData->m_Prev; pred != limit; pred = pred->m_Prev) { + // If a variable from 'pred' is not present in 'result', place it there. + for (auto& pair : *pred) + if (result.find(pair.first) == result.end()) + result[pair.first] = &pair.second; + } + } + + return result; +} + +void TBRAnalyzer::merge(VarsData* targetData, VarsData* mergeData) { + auto* LCA = findLowestCommonAncestor(targetData, mergeData); + auto collectedMergeData = + collectDataFromPredecessors(mergeData, /*limit=*/LCA); + + // For every variable in 'collectedMergeData', search it in targetData and all + // its predecessors (if found in a predecessor, make a copy to targetData). + for (auto& pair : collectedMergeData) { + VarData* found = nullptr; + auto elemSearch = targetData->find(pair.first); + if (elemSearch == targetData->end()) { + auto* branch = targetData->m_Prev; + while (branch) { + auto it = branch->find(pair.first); + if (it != branch->end()) { + (*targetData)[pair.first] = copy(it->second); + found = &(*targetData)[pair.first]; + break; + } + branch = branch->m_Prev; + } + } else { + found = &elemSearch->second; + } + + // If the variable was found, perform a merge. Else, just copy it from + // collectedMergeData. + if (found) + merge(*found, *pair.second); + else + (*targetData)[pair.first] = copy(*pair.second); + } + + // For every variable in collected targetData predecessors, search it inside + // collectedMergeData. If it's not found, that means it was not used anywhere + // between LCA and mergeData. To correctly merge, we have to take it from + // LCA's predecessors and merge it to targetData. If targetData is LCA, LCA + // will come after targetData->m_Prev and collectDataFromPredecessors will not + // reach the limit. + if (targetData != LCA) { + for (auto& pair : + collectDataFromPredecessors(targetData->m_Prev, /*limit=*/LCA)) { + auto elemSearch = collectedMergeData.find(pair.first); + if (elemSearch == collectedMergeData.end()) { + auto* branch = LCA; + while (branch) { + auto it = branch->find(pair.first); + if (it != branch->end()) { + (*targetData)[pair.first] = copy(*pair.second); + merge((*targetData)[pair.first], it->second); + break; + } + branch = branch->m_Prev; + } + } + } + } + // For every variable in targetData, search it inside collectedMergeData. If + // it's not found, that means it was not used anywhere between LCA and + // mergeData. To correctly merge, we have to take it from LCA's predecessors + // and merge it to targetData. + for (auto& pair : *targetData) { + auto elemSearch = collectedMergeData.find(pair.first); + if (elemSearch == collectedMergeData.end()) { + auto* branch = LCA; + while (branch) { + auto it = branch->find(pair.first); + if (it != branch->end()) { + merge(pair.second, it->second); + break; + } + branch = branch->m_Prev; + } + } + } +} + +bool TBRAnalyzer::VisitDeclRefExpr(DeclRefExpr* DRE) { + if (const auto* VD = dyn_cast(DRE->getDecl())) { + auto& curBranch = getCurBlockVarsData(); + if (curBranch.find(VD) == curBranch.end()) + copyVarToCurBlock(VD); + } + + setIsRequired(DRE); + + return true; +} + +bool TBRAnalyzer::VisitDeclStmt(DeclStmt* DS) { + for (auto* D : DS->decls()) { + if (auto* VD = dyn_cast(D)) { + addVar(VD); + if (clang::Expr* init = VD->getInit()) { + setMode(Mode::kMarkingMode); + TraverseStmt(init); + resetMode(); + auto& VDExpr = getCurBlockVarsData()[VD]; + // if the declared variable is ref type attach its VarData to the + // VarData of the RHS variable. + llvm::SmallVector ExprsToStore; + utils::GetInnermostReturnExpr(init, ExprsToStore); + if (VDExpr.m_Type == VarData::REF_TYPE && !ExprsToStore.empty()) + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) + VDExpr.m_Val.m_RefData = ExprsToStore[0]; + } + } + } + return true; +} + +bool TBRAnalyzer::VisitConditionalOperator(clang::ConditionalOperator* CO) { + setMode(0); + TraverseStmt(CO->getCond()); + resetMode(); + + auto elseBranch = std::move(m_BlockData[m_CurBlockID]); + + m_BlockData[m_CurBlockID] = std::unique_ptr(new VarsData()); + m_BlockData[m_CurBlockID]->m_Prev = elseBranch.get(); + TraverseStmt(CO->getTrueExpr()); + + auto thenBranch = std::move(m_BlockData[m_CurBlockID]); + m_BlockData[m_CurBlockID] = std::move(elseBranch); + TraverseStmt(CO->getTrueExpr()); + + merge(m_BlockData[m_CurBlockID].get(), thenBranch.get()); + return true; +} + +bool TBRAnalyzer::VisitBinaryOperator(BinaryOperator* BinOp) { + const auto opCode = BinOp->getOpcode(); + Expr* L = BinOp->getLHS(); + Expr* R = BinOp->getRHS(); + // Addition is not able to create any differential influence by itself so + // markingMode should be left as it is. Similarly, addition does not affect + // linearity so kNonLinearMode shouldn't be changed as well. The same applies + // to subtraction. + if (opCode == BO_Add || opCode == BO_Sub) { + TraverseStmt(L); + TraverseStmt(R); + } else if (opCode == BO_Mul) { + // Multiplication results in a linear expression if and only if one of the + // factors is constant. + Expr::EvalResult dummy; + bool nonLinear = + !clad_compat::Expr_EvaluateAsConstantExpr(R, dummy, m_Context) && + !clad_compat::Expr_EvaluateAsConstantExpr(L, dummy, m_Context); + if (nonLinear) + startNonLinearMode(); + + TraverseStmt(L); + TraverseStmt(R); + + if (nonLinear) + resetMode(); + } else if (opCode == BO_Div) { + // Division normally only results in a linear expression when the + // denominator is constant. + Expr::EvalResult dummy; + bool nonLinear = + !clad_compat::Expr_EvaluateAsConstantExpr(R, dummy, m_Context); + if (nonLinear) + startNonLinearMode(); + + TraverseStmt(L); + TraverseStmt(R); + + if (nonLinear) + resetMode(); + } else if (BinOp->isAssignmentOp()) { + if (opCode == BO_Assign || opCode == BO_AddAssign || + opCode == BO_SubAssign) { + // Since we only care about non-linear usages of variables, there is + // no difference between operators =, -=, += in terms of TBR analysis. + TraverseStmt(L); + + startMarkingMode(); + TraverseStmt(R); + resetMode(); + } else if (opCode == BO_MulAssign || opCode == BO_DivAssign) { + // *= (/=) normally only performs a linear operation if and only if + // the RHS is constant. If RHS is not constant, 'x *= y' ('x /= y') + // represents the same operation as 'x = x * y' ('x = x / y') and, + // therefore, LHS has to be visited in kMarkingMode|kNonLinearMode. + Expr::EvalResult dummy; + bool RisNotConst = + !clad_compat::Expr_EvaluateAsConstantExpr(R, dummy, m_Context); + if (RisNotConst) + setMode(Mode::kMarkingMode | Mode::kNonLinearMode); + TraverseStmt(L); + if (RisNotConst) + resetMode(); + + setMode(Mode::kMarkingMode | Mode::kNonLinearMode); + TraverseStmt(R); + resetMode(); + } + llvm::SmallVector ExprsToStore; + utils::GetInnermostReturnExpr(L, ExprsToStore); + for (const auto* innerExpr : ExprsToStore) { + // Mark corresponding SourceLocation as required/not required to be + // stored for all expressions that could be used changed. + markLocation(innerExpr); + // Set them to not required to store because the values were changed. + // (if some value was not changed, this could only happen if it was + // already not required to store). + setIsRequired(innerExpr, /*isReq=*/false); + } + } else if (opCode == BO_Comma) { + setMode(0); + TraverseStmt(L); + resetMode(); + + TraverseStmt(R); + } + // else { + // FIXME: add logic/bitwise/comparison operators + // } + return true; +} + +bool TBRAnalyzer::VisitUnaryOperator(clang::UnaryOperator* UnOp) { + const auto opCode = UnOp->getOpcode(); + Expr* E = UnOp->getSubExpr(); + TraverseStmt(E); + if (opCode == UO_PostInc || opCode == UO_PostDec || opCode == UO_PreInc || + opCode == UO_PreDec) { + // FIXME: this doesn't support all the possible references + // Mark corresponding SourceLocation as required/not required to be + // stored for all expressions that could be used in this operation. + llvm::SmallVector ExprsToStore; + utils::GetInnermostReturnExpr(E, ExprsToStore); + for (const auto* innerExpr : ExprsToStore) { + // Mark corresponding SourceLocation as required/not required to be + // stored for all expressions that could be changed. + markLocation(innerExpr); + } + } + // FIXME: Ideally, `__real` and `__imag` operators should be treated as member + // expressions. However, it is not clear where the FieldDecls of real and + // imaginary parts should be deduced from (their names might be + // compiler-specific). So for now we visit the whole subexpression. + return true; +} + +bool TBRAnalyzer::VisitCallExpr(clang::CallExpr* CE) { + // FIXME: Currently TBR analysis just stops here and assumes that all the + // variables passed by value/reference are used/used and changed. Analysis + // could proceed to the function to analyse data flow inside it. + FunctionDecl* FD = CE->getDirectCallee(); + bool noHiddenParam = (CE->getNumArgs() == FD->getNumParams()); + setMode(Mode::kMarkingMode | Mode::kNonLinearMode); + for (std::size_t i = 0, e = CE->getNumArgs(); i != e; ++i) { + clang::Expr* arg = CE->getArg(i); + bool passByRef = false; + if (noHiddenParam) + passByRef = FD->getParamDecl(i)->getType()->isReferenceType(); + else if (i != 0) + passByRef = FD->getParamDecl(i - 1)->getType()->isReferenceType(); + setMode(Mode::kMarkingMode | Mode::kNonLinearMode); + TraverseStmt(arg); + resetMode(); + const auto* B = arg->IgnoreParenImpCasts(); + // FIXME: this supports only DeclRefExpr + if (passByRef) { + // Mark SourceLocation as required to store for ref-type arguments. + if (isa(B) || isa(B)) { + m_TBRLocs.insert(arg->getBeginLoc()); + setIsRequired(arg, /*isReq=*/false); + } + } + } + resetMode(); + return true; +} + +bool TBRAnalyzer::VisitCXXConstructExpr(clang::CXXConstructExpr* CE) { + // FIXME: Currently TBR analysis just stops here and assumes that all the + // variables passed by value/reference are used/used and changed. Analysis + // could proceed to the constructor to analyse data flow inside it. + // FIXME: add support for default values + FunctionDecl* FD = CE->getConstructor(); + setMode(Mode::kMarkingMode | Mode::kNonLinearMode); + for (std::size_t i = 0, e = CE->getNumArgs(); i != e; ++i) { + auto* arg = CE->getArg(i); + bool passByRef = FD->getParamDecl(i)->getType()->isReferenceType(); + setMode(Mode::kMarkingMode | Mode::kNonLinearMode); + TraverseStmt(arg); + resetMode(); + const auto* B = arg->IgnoreParenImpCasts(); + // FIXME: this supports only DeclRefExpr + if (passByRef) { + // Mark SourceLocation as required for ref-type arguments. + if (isa(B) || isa(B)) { + m_TBRLocs.insert(arg->getBeginLoc()); + setIsRequired(arg, /*isReq=*/false); + } + } + } + resetMode(); + return true; +} + +bool TBRAnalyzer::VisitMemberExpr(clang::MemberExpr* ME) { + setIsRequired(ME); + return true; +} + +bool TBRAnalyzer::VisitArraySubscriptExpr(clang::ArraySubscriptExpr* ASE) { + setMode(0); + TraverseStmt(ASE->getBase()); + resetMode(); + setIsRequired(ASE); + setMode(Mode::kMarkingMode | Mode::kNonLinearMode); + TraverseStmt(ASE->getIdx()); + resetMode(); + return true; +} + +bool TBRAnalyzer::VisitInitListExpr(clang::InitListExpr* ILE) { + setMode(Mode::kMarkingMode); + for (auto* init : ILE->inits()) + TraverseStmt(init); + resetMode(); + return true; +} + +} // end namespace clad diff --git a/lib/Differentiator/TBRAnalyzer.h b/lib/Differentiator/TBRAnalyzer.h new file mode 100644 index 000000000..d1f772757 --- /dev/null +++ b/lib/Differentiator/TBRAnalyzer.h @@ -0,0 +1,320 @@ +#ifndef CLAD_DIFFERENTIATOR_TBRANALYZER_H +#define CLAD_DIFFERENTIATOR_TBRANALYZER_H + +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Analysis/CFG.h" + +#include "clad/Differentiator/CladUtils.h" +#include "clad/Differentiator/Compatibility.h" + +#include +#include + +using namespace clang; + +namespace clad { + +/// Gradient computation requres reversal of the control flow of the original +/// program becomes necessary. To guarantee correctness, certain values that are +/// computed and overwritten in the original program must be made available in +/// the adjoint program. They can be determined by performing a static data flow +/// analysis, the so-called To-Be-Recorded (TBR) analysis. Overestimation of +/// this set must be kept minimal to get efficient adjoint codes. +/// +/// This class implements this to-be-recorded analysis. +class TBRAnalyzer : public clang::RecursiveASTVisitor { + /// ProfileID is the key type for ArrMap used to represent array indices + /// and object fields. + using ProfileID = clad_compat::FoldingSetNodeID; + + ProfileID getProfileID(const Expr* E) const { + ProfileID profID; + E->Profile(profID, m_Context, /* Canonical */ true); + return profID; + } + + static ProfileID getProfileID(const FieldDecl* FD) { + ProfileID profID; + profID.AddPointer(FD); + return profID; + } + + struct ProfileIDHash { + size_t operator()(const ProfileID& x) const { return x.ComputeHash(); } + }; + + struct VarData; + using ArrMap = std::unordered_map; + + // NOLINTBEGIN(cppcoreguidelines-pro-type-union-access) + + /// Stores all the necessary information about one variable. Fundamental type + /// variables need only one bit. An object/array needs a separate VarData for + /// each field/element. Reference type variables store the clang::Expr* they + /// refer to. UNDEFINED is used whenever the type of a node cannot be + /// determined. + /// + /// FIXME: Pointers to objects are considered OBJ_TYPE for simplicity. This + /// approach might cause problems when the support for pointers is added. + /// + /// FIXME: Add support for references to call expression results. + /// 'double& x = f(b);' is not supported. + struct VarData { + enum VarDataType { UNDEFINED, FUND_TYPE, OBJ_TYPE, ARR_TYPE, REF_TYPE }; + union VarDataValue { + bool m_FundData; + /// m_ArrData is stored as pointers for VarDataValue to take + /// less space. + /// Both arrays and and objects are modelled using m_ArrData; + std::unique_ptr m_ArrData; + Expr* m_RefData; + VarDataValue() : m_ArrData(nullptr) {} + /// `= default` cannot be used here since + /// default destructor is implicitly deleted. + // NOLINTNEXTLINE(modernize-use-equals-default) + ~VarDataValue() {} + }; + VarDataType m_Type = UNDEFINED; + VarDataValue m_Val; + + VarData() = default; + VarData(const VarData& other) = delete; + VarData(VarData&& other) noexcept : m_Type(other.m_Type) { + *this = std::move(other); + } + VarData& operator=(const VarData& other) = delete; + VarData& operator=(VarData&& other) noexcept { + m_Type = other.m_Type; + if (m_Type == FUND_TYPE) { + m_Val.m_FundData = other.m_Val.m_FundData; + } else if (m_Type == OBJ_TYPE || m_Type == ARR_TYPE) { + m_Val.m_ArrData = std::move(other.m_Val.m_ArrData); + other.m_Val.m_ArrData = nullptr; + } else if (m_Type == REF_TYPE) { + m_Val.m_RefData = other.m_Val.m_RefData; + } + other.m_Type = UNDEFINED; + return *this; + } + + /// Builds a VarData object (and its children) based on the provided type. + VarData(QualType QT); + + /// Erases all children VarData's of this VarData. + ~VarData() { + if (m_Type == OBJ_TYPE || m_Type == ARR_TYPE) + m_Val.m_ArrData.reset(); + } + }; + // NOLINTEND(cppcoreguidelines-pro-type-union-access) + + /// Recursively sets all the leaves' bools to isReq. + void setIsRequired(VarData& varData, bool isReq = true); + /// Whenever an array element with a non-constant index is set to required + /// this function is used to set to required all the array elements that + /// could match that element (e.g. set 'a[1].y' and 'a[6].y' to required + /// when 'a[k].y' is set to required). Takes unwrapped sequence of + /// indices/members of the expression being overlaid and the index of of the + /// current index/member. + void overlay(VarData& targetData, llvm::SmallVector& IDSequence, + size_t i); + /// Returns true if there is at least one required to store node among + /// child nodes. + bool findReq(const VarData& varData); + /// Used to merge together VarData for one variable from two branches + /// (e.g. after an if-else statements). Look at the Control Flow section for + /// more information. + void merge(VarData& targetData, VarData& mergeData); + /// Used to recursively copy VarData when separating into different branches + /// (e.g. when entering an if-else statements). Look at the Control Flow + /// section for more information. + VarData copy(VarData& copyData); + + clang::CFGBlock* getCFGBlockByID(unsigned ID); + + /// Given a MemberExpr*/ArraySubscriptExpr* return a pointer to its + /// corresponding VarData. If the given element of an array does not have a + /// VarData yet it will be added automatically. If addNonConstIdx==false this + /// will return the last VarData before the non-constant index + /// (e.g. for 'x.arr[k+1].y' the return value will be the VarData of x.arr). + /// Otherwise, non-const indices will be represented as index -1. + VarData* getMemberVarData(const clang::MemberExpr* ME, + bool addNonConstIdx = false); + VarData* getArrSubVarData(const clang::ArraySubscriptExpr* ASE, + bool addNonConstIdx = false); + /// Given an Expr* returns its corresponding VarData. + VarData* getExprVarData(const clang::Expr* E, bool addNonConstIdx = false); + + /// Whenever an array element with a non-constant index is set to required + /// this function is used to set to required all the array elements that + /// could match that element (e.g. set 'a[1].y' and 'a[6].y' to required when + /// 'a[k].y' is set to required). Unwraps the a given expression into a + /// sequence of indices/members of the expression being overlaid and calls + /// VarData::overlay() recursively. + void overlay(const clang::Expr* E); + + /// Used to store all the necessary information about variables at a + /// particular moment. + /// Note: the VarsData of one CFG block only stores information specific + /// to that block and relies on the VarsData of it's predecessors + /// for old information. This is done to avoid excessive copying + /// memory and usage. + /// Note: 'this' pointer does not have a declaration so nullptr is used as + /// its key instead. + struct VarsData { + std::unordered_map m_Data; + VarsData* m_Prev = nullptr; + + VarsData() = default; + VarsData(const VarsData& other) = default; + ~VarsData() = default; + VarsData(VarsData&& other) noexcept + : m_Data(std::move(other.m_Data)), m_Prev(other.m_Prev) {} + VarsData& operator=(const VarsData& other) = delete; + VarsData& operator=(VarsData&& other) noexcept { + if (&m_Data == &other.m_Data) { + m_Data = std::move(other.m_Data); + m_Prev = other.m_Prev; + } + return *this; + } + + using iterator = + std::unordered_map::iterator; + iterator begin() { return m_Data.begin(); } + iterator end() { return m_Data.end(); } + VarData& operator[](const clang::VarDecl* VD) { return m_Data[VD]; } + iterator find(const clang::VarDecl* VD) { return m_Data.find(VD); } + void clear() { m_Data.clear(); } + }; + + /// Collects the data from 'varsData' and its predecessors until + /// 'limit' into one map ('limit' VarsData is not included). + /// If 'limit' is 'nullptr', data is collected starting with + /// the entry CFG block. + /// Note: the returned VarsData contains original data from + /// the predecessors (NOT copies). It should not be modified. + std::unordered_map< + const clang::VarDecl*, + VarData*> static collectDataFromPredecessors(VarsData* varsData, + VarsData* limit = nullptr); + + /// Finds the lowest common ancestor of two VarsData + /// (based on the m_Prev field in VarsData). + static VarsData* findLowestCommonAncestor(VarsData* varsData1, + VarsData* varsData2); + + /// Merges mergeData into targetData. Should be called + /// after mergeData is passed and the corresponding CFG + /// block is one of the predecessors of targetData's CFG block + /// (e.g. instance when merging if- and else- blocks). + /// Note: The first predecessor (targetData->m_Prev) does NOT have + /// to be merged to targetData. + void merge(VarsData* targetData, VarsData* mergeData); + + /// Used to find DeclRefExpr's that will be used in the backwards pass. + /// In order to be marked as required, a variables has to appear in a place + /// where it would have a differential influence and will appear non-linearly + /// (e.g. for 'x = 2 * y;', y will not appear in the backwards pass). Hence, + /// markingMode and nonLinearMode. + enum Mode { kMarkingMode = 1, kNonLinearMode = 2 }; + /// Tells if the variable at a given location is required to store. Basically, + /// is the result of analysis. + std::set m_TBRLocs; + + /// Stores modes in a stack (used to retrieve the old mode after entering + /// a new one). + std::vector m_ModeStack; + + ASTContext& m_Context; + + /// clang::CFG of the function being analysed. + std::unique_ptr m_CFG; + + /// Stores VarsData structures for CFG blocks (the indices in + /// the vector correspond to CFG blocks' IDs) + std::vector> m_BlockData; + + /// Stores the number of performed passes for a given CFG block index. + std::vector m_BlockPassCounter; + + /// ID of the CFG block being visited. + unsigned m_CurBlockID{}; + + /// The set of IDs of the CFG blocks that should be visited. + std::set m_CFGQueue; + + /// Set to true when a non-const index is found while analysing an + /// array subscript expression. + bool m_NonConstIndexFound = false; + + //// Setters + /// Creates VarData for a new VarDecl*. + void addVar(const clang::VarDecl* VD); + /// Makes a copy of the VarData corresponding to VD + /// to the current block from the lowest predecessor + /// where VD is present. + void copyVarToCurBlock(const clang::VarDecl* VD); + /// Marks the SourceLocation of E if it is required to store. + /// E could be DeclRefExpr*, ArraySubscriptExpr* or MemberExpr*. + void markLocation(const clang::Expr* E); + /// Sets E's corresponding VarData (or all its child nodes) to + /// required/not required. For isReq==true, checks if the current mode is + /// markingMode and nonLinearMode. E could be DeclRefExpr*, + /// ArraySubscriptExpr* or MemberExpr*. + void setIsRequired(const clang::Expr* E, bool isReq = true); + + /// Returns the VarsData of the CFG block being visited. + VarsData& getCurBlockVarsData() { return *m_BlockData[m_CurBlockID]; } + + //// Modes Setters + /// Sets the mode manually + void setMode(int mode) { m_ModeStack.push_back(mode); } + /// Sets nonLinearMode but leaves markingMode just as it was. + void startNonLinearMode() { + m_ModeStack.push_back(m_ModeStack.back() | Mode::kNonLinearMode); + } + /// Sets markingMode but leaves nonLinearMode just as it was. + void startMarkingMode() { + m_ModeStack.push_back(Mode::kMarkingMode | m_ModeStack.back()); + } + /// Removes the last mode in the stack (retrieves the previous one). + void resetMode() { m_ModeStack.pop_back(); } + +public: + /// Constructor + TBRAnalyzer(ASTContext& Context) : m_Context(Context) { + m_ModeStack.push_back(0); + } + + /// Destructor + ~TBRAnalyzer() = default; + + /// Delete copy/move operators and constructors. + TBRAnalyzer(const TBRAnalyzer&) = delete; + TBRAnalyzer& operator=(const TBRAnalyzer&) = delete; + TBRAnalyzer(const TBRAnalyzer&&) = delete; + TBRAnalyzer& operator=(const TBRAnalyzer&&) = delete; + + /// Returns the result of the whole analysis + std::set getResult() { return m_TBRLocs; } + + /// Visitors + void Analyze(const clang::FunctionDecl* FD); + + void VisitCFGBlock(const clang::CFGBlock& block); + + bool VisitArraySubscriptExpr(clang::ArraySubscriptExpr* ASE); + bool VisitBinaryOperator(clang::BinaryOperator* BinOp); + bool VisitCallExpr(clang::CallExpr* CE); + bool VisitConditionalOperator(clang::ConditionalOperator* CO); + bool VisitCXXConstructExpr(clang::CXXConstructExpr* CE); + bool VisitDeclRefExpr(clang::DeclRefExpr* DRE); + bool VisitDeclStmt(clang::DeclStmt* DS); + bool VisitInitListExpr(clang::InitListExpr* ILE); + bool VisitMemberExpr(clang::MemberExpr* ME); + bool VisitUnaryOperator(clang::UnaryOperator* UnOp); +}; + +} // end namespace clad +#endif // CLAD_DIFFERENTIATOR_TBRANALYZER_H diff --git a/lib/Differentiator/VisitorBase.cpp b/lib/Differentiator/VisitorBase.cpp index 279b7bf5d..404a350dd 100644 --- a/lib/Differentiator/VisitorBase.cpp +++ b/lib/Differentiator/VisitorBase.cpp @@ -84,7 +84,8 @@ namespace clad { } void VisitorBase::updateReferencesOf(Stmt* InSubtree) { - utils::ReferencesUpdater up(m_Sema, getCurrentScope(), m_Function); + utils::ReferencesUpdater up(m_Sema, getCurrentScope(), m_Function, + m_DeclReplacements); up.TraverseStmt(InSubtree); } @@ -168,9 +169,10 @@ namespace clad { } DeclStmt* VisitorBase::BuildDeclStmt(Decl* D) { - Stmt* DS = - m_Sema.ActOnDeclStmt(m_Sema.ConvertDeclToDeclGroup(D), noLoc, noLoc) - .get(); + Stmt* DS = m_Sema + .ActOnDeclStmt(m_Sema.ConvertDeclToDeclGroup(D), + D->getBeginLoc(), D->getEndLoc()) + .get(); return cast(DS); } @@ -184,7 +186,7 @@ namespace clad { QualType T = D->getType(); T = T.getNonReferenceType(); return cast(clad_compat::GetResult( - m_Sema.BuildDeclRefExpr(D, T, VK_LValue, noLoc, SS))); + m_Sema.BuildDeclRefExpr(D, T, VK_LValue, D->getBeginLoc(), SS))); } IdentifierInfo* @@ -303,7 +305,8 @@ namespace clad { QualType VisitorBase::CloneType(const QualType QT) { auto clonedType = m_Builder.m_NodeCloner->CloneType(QT); - utils::ReferencesUpdater up(m_Sema, getCurrentScope(), m_Function); + utils::ReferencesUpdater up(m_Sema, getCurrentScope(), m_Function, + m_DeclReplacements); up.updateType(clonedType); return clonedType; } diff --git a/test/Analyses/TBR.cpp b/test/Analyses/TBR.cpp new file mode 100644 index 000000000..17be557b1 --- /dev/null +++ b/test/Analyses/TBR.cpp @@ -0,0 +1,26 @@ +// RUN: %cladclang -mllvm -debug-only=clad-tbr -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oReverseLoops.out 2>&1 | FileCheck %s +// REQUIRES: asserts +//CHECK-NOT: {{.*error|warning|note:.*}} + +#include "clad/Differentiator/Differentiator.h" + +double f1(double x) { + double t = 1; + for (int i = 0; i < 3; i++) + t *= x; + return t; +} // == x^3 + +#define TEST(F, x) { \ + result[0] = 0; \ + auto F##grad = clad::gradient(F);\ + F##grad.execute(x, result);\ + printf("{%.2f}\n", result[0]); \ +} + +int main() { + double result[3] = {}; + clad::array_ref result_ref(result, 3); + TEST(f1, 3); // CHECK-EXEC: {27.00} + +} diff --git a/test/Arrays/ArrayInputsReverseMode.C b/test/Arrays/ArrayInputsReverseMode.C index 44d433838..35874ca1d 100644 --- a/test/Arrays/ArrayInputsReverseMode.C +++ b/test/Arrays/ArrayInputsReverseMode.C @@ -1,7 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -Wno-unused-value -oArrayInputsReverseMode.out 2>&1 | FileCheck %s // RUN: ./ArrayInputsReverseMode.out | FileCheck -check-prefix=CHECK-EXEC %s - -// XFAIL: asserts +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -Wno-unused-value -oArrayInputsReverseMode.out +// RUN: ./ArrayInputsReverseMode.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -19,22 +19,24 @@ double addArr(const double *arr, int n) { //CHECK-NEXT: double _d_ret = 0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: double ret = 0; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < n; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: ret += arr[clad::push(_t1, i)]; +//CHECK-NEXT: clad::push(_t1, ret); +//CHECK-NEXT: ret += arr[i]; //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_ret += _d_y; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: ret = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_ret; //CHECK-NEXT: _d_ret += _r_d0; -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: _d_arr[_t2] += _r_d0; +//CHECK-NEXT: _d_arr[i] += _r_d0; //CHECK-NEXT: _d_ret -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: } @@ -50,6 +52,7 @@ double f(double *arr) { //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { +//CHECK-NEXT: arr = _t0; //CHECK-NEXT: int _grad1 = 0; //CHECK-NEXT: addArr_pullback(_t0, 3, 1, _d_arr, &_grad1); //CHECK-NEXT: clad::array _r0(_d_arr); @@ -70,40 +73,37 @@ float func(float* a, float* b) { //CHECK-NEXT: float _d_sum = 0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t3 = {}; -//CHECK-NEXT: clad::tape _t4 = {}; -//CHECK-NEXT: clad::tape _t5 = {}; -//CHECK-NEXT: clad::tape _t7 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: float sum = 0; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < 3; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: float _ref0 = a[clad::push(_t1, i)]; -//CHECK-NEXT: clad::push(_t4, _ref0); -//CHECK-NEXT: _ref0 *= clad::push(_t3, b[clad::push(_t5, i)]); -//CHECK-NEXT: sum += a[clad::push(_t7, i)]; +//CHECK-NEXT: clad::push(_t1, a[i]); +//CHECK-NEXT: a[i] *= b[i]; +//CHECK-NEXT: clad::push(_t2, sum); +//CHECK-NEXT: sum += a[i]; //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: sum = clad::pop(_t2); //CHECK-NEXT: float _r_d1 = _d_sum; //CHECK-NEXT: _d_sum += _r_d1; -//CHECK-NEXT: int _t8 = clad::pop(_t7); -//CHECK-NEXT: _d_a[_t8] += _r_d1; +//CHECK-NEXT: _d_a[i] += _r_d1; //CHECK-NEXT: _d_sum -= _r_d1; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: float _r_d0 = _d_a[_t2]; -//CHECK-NEXT: _d_a[_t2] += _r_d0 * clad::pop(_t3); -//CHECK-NEXT: float _r0 = clad::pop(_t4) * _r_d0; -//CHECK-NEXT: int _t6 = clad::pop(_t5); -//CHECK-NEXT: _d_b[_t6] += _r0; -//CHECK-NEXT: _d_a[_t2] -= _r_d0; -//CHECK-NEXT: _d_a[_t2]; +//CHECK-NEXT: a[i] = clad::pop(_t1); +//CHECK-NEXT: float _r_d0 = _d_a[i]; +//CHECK-NEXT: _d_a[i] += _r_d0 * b[i]; +//CHECK-NEXT: float _r0 = a[i] * _r_d0; +//CHECK-NEXT: _d_b[i] += _r0; +//CHECK-NEXT: _d_a[i] -= _r_d0; +//CHECK-NEXT: _d_a[i]; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: } @@ -113,12 +113,10 @@ float helper(float x) { } // CHECK: void helper_pullback(float x, float _d_y, clad::array_ref _d_x) { -// CHECK-NEXT: float _t0; -// CHECK-NEXT: _t0 = x; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: float _r0 = _d_y * _t0; +// CHECK-NEXT: float _r0 = _d_y * x; // CHECK-NEXT: float _r1 = 2 * _d_y; // CHECK-NEXT: * _d_x += _r1; // CHECK-NEXT: } @@ -135,25 +133,26 @@ float func2(float* a) { //CHECK-NEXT: float _d_sum = 0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t3 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: float sum = 0; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < 3; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: sum += helper(clad::push(_t3, a[clad::push(_t1, i)])); +//CHECK-NEXT: clad::push(_t1, sum); +//CHECK-NEXT: sum += helper(a[i]); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; +//CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: float _r_d0 = _d_sum; //CHECK-NEXT: _d_sum += _r_d0; //CHECK-NEXT: float _grad0 = 0.F; -//CHECK-NEXT: helper_pullback(clad::pop(_t3), _r_d0, &_grad0); +//CHECK-NEXT: helper_pullback(a[i], _r_d0, &_grad0); //CHECK-NEXT: float _r0 = _grad0; -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: _d_a[_t2] += _r0; +//CHECK-NEXT: _d_a[i] += _r0; //CHECK-NEXT: _d_sum -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: } @@ -169,27 +168,30 @@ float func3(float* a, float* b) { //CHECK-NEXT: float _d_sum = 0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t3 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: float sum = 0; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < 3; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: sum += (a[clad::push(_t1, i)] += b[clad::push(_t3, i)]); +//CHECK-NEXT: clad::push(_t1, sum); +//CHECK-NEXT: clad::push(_t2, a[i]); +//CHECK-NEXT: sum += (a[i] += b[i]); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; +//CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: float _r_d0 = _d_sum; //CHECK-NEXT: _d_sum += _r_d0; -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: float _r_d1 = _d_a[_t2]; -//CHECK-NEXT: _d_a[_t2] += _r_d1; -//CHECK-NEXT: int _t4 = clad::pop(_t3); -//CHECK-NEXT: _d_b[_t4] += _r_d1; -//CHECK-NEXT: _d_a[_t2] -= _r_d1; -//CHECK-NEXT: _d_a[_t2] += _r_d0; +//CHECK-NEXT: _d_a[i] += _r_d0; +//CHECK-NEXT: a[i] = clad::pop(_t2); +//CHECK-NEXT: float _r_d1 = _d_a[i]; +//CHECK-NEXT: _d_a[i] += _r_d1; +//CHECK-NEXT: _d_b[i] += _r_d1; +//CHECK-NEXT: _d_a[i] -= _r_d1; //CHECK-NEXT: _d_sum -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: } @@ -204,48 +206,43 @@ double func4(double x) { } //CHECK: void func4_grad(double x, clad::array_ref _d_x) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; //CHECK-NEXT: clad::array _d_arr(3UL); //CHECK-NEXT: double _d_sum = 0; -//CHECK-NEXT: unsigned long _t3; +//CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape > _t4 = {}; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t2 = x; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: double arr[3] = {x, 2 * _t0, _t2 * _t1}; +//CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: double arr[3] = {x, 2 * x, x * x}; //CHECK-NEXT: double sum = 0; -//CHECK-NEXT: _t3 = 0; +//CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < 3; i++) { -//CHECK-NEXT: _t3++; -//CHECK-NEXT: clad::push(_t4, clad::array(arr, 3UL)); +//CHECK-NEXT: _t0++; +//CHECK-NEXT: clad::push(_t1, sum); //CHECK-NEXT: sum += addArr(arr, 3); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; -//CHECK-NEXT: for (; _t3; _t3--) { +//CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_sum; //CHECK-NEXT: _d_sum += _r_d0; -//CHECK-NEXT: clad::array _r5 = clad::pop(_t4); //CHECK-NEXT: int _grad1 = 0; -//CHECK-NEXT: addArr_pullback(_r5, 3, _r_d0, _d_arr, &_grad1); +//CHECK-NEXT: addArr_pullback(arr, 3, _r_d0, _d_arr, &_grad1); //CHECK-NEXT: clad::array _r4(_d_arr); -//CHECK-NEXT: int _r6 = _grad1; +//CHECK-NEXT: int _r5 = _grad1; //CHECK-NEXT: _d_sum -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: * _d_x += _d_arr[0]; -//CHECK-NEXT: double _r0 = _d_arr[1] * _t0; +//CHECK-NEXT: double _r0 = _d_arr[1] * x; //CHECK-NEXT: double _r1 = 2 * _d_arr[1]; //CHECK-NEXT: * _d_x += _r1; -//CHECK-NEXT: double _r2 = _d_arr[2] * _t1; +//CHECK-NEXT: double _r2 = _d_arr[2] * x; //CHECK-NEXT: * _d_x += _r2; -//CHECK-NEXT: double _r3 = _t2 * _d_arr[2]; +//CHECK-NEXT: double _r3 = x * _d_arr[2]; //CHECK-NEXT: * _d_x += _r3; //CHECK-NEXT: } //CHECK-NEXT: } @@ -267,50 +264,52 @@ double func5(int k) { //CHECK-NEXT: int _d_n = 0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: double _d_sum = 0; -//CHECK-NEXT: unsigned long _t3; +//CHECK-NEXT: unsigned long _t2; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape > _t4 = {}; -//CHECK-NEXT: clad::tape _t5 = {}; +//CHECK-NEXT: clad::tape _t3 = {}; //CHECK-NEXT: int n = k; //CHECK-NEXT: clad::array _d_arr(n); //CHECK-NEXT: double arr[n]; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < n; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: arr[clad::push(_t1, i)] = k; +//CHECK-NEXT: clad::push(_t1, arr[i]); +//CHECK-NEXT: arr[i] = k; //CHECK-NEXT: } //CHECK-NEXT: double sum = 0; -//CHECK-NEXT: _t3 = 0; +//CHECK-NEXT: _t2 = 0; //CHECK-NEXT: for (int i = 0; i < 3; i++) { -//CHECK-NEXT: _t3++; -//CHECK-NEXT: clad::push(_t4, clad::array(arr, n)); -//CHECK-NEXT: sum += addArr(arr, clad::push(_t5, n)); +//CHECK-NEXT: _t2++; +//CHECK-NEXT: clad::push(_t3, sum); +//CHECK-NEXT: sum += addArr(arr, n); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; -//CHECK-NEXT: for (; _t3; _t3--) { +//CHECK-NEXT: for (; _t2; _t2--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: sum = clad::pop(_t3); //CHECK-NEXT: double _r_d1 = _d_sum; //CHECK-NEXT: _d_sum += _r_d1; -//CHECK-NEXT: clad::array _r1 = clad::pop(_t4); //CHECK-NEXT: int _grad1 = 0; -//CHECK-NEXT: addArr_pullback(_r1, clad::pop(_t5), _r_d1, _d_arr, &_grad1); +//CHECK-NEXT: addArr_pullback(arr, n, _r_d1, _d_arr, &_grad1); //CHECK-NEXT: clad::array _r0(_d_arr); -//CHECK-NEXT: int _r2 = _grad1; -//CHECK-NEXT: _d_n += _r2; +//CHECK-NEXT: int _r1 = _grad1; +//CHECK-NEXT: _d_n += _r1; //CHECK-NEXT: _d_sum -= _r_d1; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: double _r_d0 = _d_arr[_t2]; +//CHECK-NEXT: arr[i] = clad::pop(_t1); +//CHECK-NEXT: double _r_d0 = _d_arr[i]; //CHECK-NEXT: * _d_k += _r_d0; -//CHECK-NEXT: _d_arr[_t2] -= _r_d0; -//CHECK-NEXT: _d_arr[_t2]; +//CHECK-NEXT: _d_arr[i] -= _r_d0; +//CHECK-NEXT: _d_arr[i]; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: * _d_k += _d_n; @@ -329,37 +328,36 @@ double func6(double seed) { //CHECK-NEXT: double _d_sum = 0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: clad::array _d_arr(3UL); -//CHECK-NEXT: clad::tape > _t3 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: double sum = 0; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < 3; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: double arr[3] = {seed, clad::push(_t2, seed) * clad::push(_t1, i), seed + i}; -//CHECK-NEXT: clad::push(_t3, clad::array(arr, 3UL)); +//CHECK-NEXT: double arr[3] = {seed, seed * i, seed + i}; +//CHECK-NEXT: clad::push(_t1, sum); //CHECK-NEXT: sum += addArr(arr, 3); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_sum; //CHECK-NEXT: _d_sum += _r_d0; -//CHECK-NEXT: clad::array _r3 = clad::pop(_t3); //CHECK-NEXT: int _grad1 = 0; -//CHECK-NEXT: addArr_pullback(_r3, 3, _r_d0, _d_arr, &_grad1); +//CHECK-NEXT: addArr_pullback(arr, 3, _r_d0, _d_arr, &_grad1); //CHECK-NEXT: clad::array _r2(_d_arr); -//CHECK-NEXT: int _r4 = _grad1; +//CHECK-NEXT: int _r3 = _grad1; //CHECK-NEXT: _d_sum -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: * _d_seed += _d_arr[0]; -//CHECK-NEXT: double _r0 = _d_arr[1] * clad::pop(_t1); +//CHECK-NEXT: double _r0 = _d_arr[1] * i; //CHECK-NEXT: * _d_seed += _r0; -//CHECK-NEXT: double _r1 = clad::pop(_t2) * _d_arr[1]; +//CHECK-NEXT: double _r1 = seed * _d_arr[1]; //CHECK-NEXT: _d_i += _r1; //CHECK-NEXT: * _d_seed += _d_arr[2]; //CHECK-NEXT: _d_i += _d_arr[2]; @@ -374,19 +372,15 @@ double inv_square(double *params) { //CHECK: void inv_square_pullback(double *params, double _d_y, clad::array_ref _d_params) { //CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t2 = params[0]; -//CHECK-NEXT: _t1 = params[0]; -//CHECK-NEXT: _t0 = (_t2 * _t1); +//CHECK-NEXT: _t0 = (params[0] * params[0]); //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: double _r0 = _d_y / _t0; //CHECK-NEXT: double _r1 = _d_y * -1 / (_t0 * _t0); -//CHECK-NEXT: double _r2 = _r1 * _t1; +//CHECK-NEXT: double _r2 = _r1 * params[0]; //CHECK-NEXT: _d_params[0] += _r2; -//CHECK-NEXT: double _r3 = _t2 * _r1; +//CHECK-NEXT: double _r3 = params[0] * _r1; //CHECK-NEXT: _d_params[0] += _r3; //CHECK-NEXT: } //CHECK-NEXT: } @@ -405,30 +399,30 @@ double func7(double *params) { //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: std::size_t _d_i = 0; //CHECK-NEXT: clad::array _d_paramsPrime(1UL); -//CHECK-NEXT: clad::tape > _t2 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: double out = 0.; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (std::size_t i = 0; i < 1; ++i) { //CHECK-NEXT: _t0++; //CHECK-NEXT: double paramsPrime[1] = {params[0]}; -//CHECK-NEXT: clad::push(_t2, clad::array(paramsPrime, 1UL)); +//CHECK-NEXT: clad::push(_t1, out); //CHECK-NEXT: out = out + inv_square(paramsPrime); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_out += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: --i; //CHECK-NEXT: { +//CHECK-NEXT: out = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_out; //CHECK-NEXT: _d_out += _r_d0; -//CHECK-NEXT: clad::array _r1 = clad::pop(_t2); -//CHECK-NEXT: inv_square_pullback(_r1, _r_d0, _d_paramsPrime); +//CHECK-NEXT: inv_square_pullback(paramsPrime, _r_d0, _d_paramsPrime); //CHECK-NEXT: clad::array _r0(_d_paramsPrime); //CHECK-NEXT: _d_out -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: int _t1 = 0; -//CHECK-NEXT: _d_params[_t1] += _d_paramsPrime[0]; +//CHECK-NEXT: _d_params[0] += _d_paramsPrime[0]; //CHECK-NEXT: _d_paramsPrime = {}; //CHECK-NEXT: } //CHECK-NEXT: } @@ -458,7 +452,7 @@ int main() { auto nested = clad::gradient(func3); nested.execute(a3, b, da3, db2); - printf("Result (b) = {%.2f, %.2f, %.2f}\n", db2[0], db2[1], db2[2]); // CHECK-EXEC: Result (b) = {0.00, 0.00, 0.00} + printf("Result (b) = {%.2f, %.2f, %.2f}\n", db2[0], db2[1], db2[2]); // CHECK-EXEC: Result (b) = {1.00, 1.00, 1.00} auto constArray = clad::gradient(func4); double _dx = 0; diff --git a/test/Arrays/Arrays.C b/test/Arrays/Arrays.C index 9718498b5..9628771e0 100644 --- a/test/Arrays/Arrays.C +++ b/test/Arrays/Arrays.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oArrays.out 2>&1 | FileCheck %s // RUN: ./Arrays.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oArrays.out +// RUN: ./Arrays.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -92,34 +94,22 @@ double const_dot_product(double x, double y, double z) { //CHECK: void const_dot_product_grad(double x, double y, double z, clad::array_ref _d_x, clad::array_ref _d_y, clad::array_ref _d_z) { //CHECK-NEXT: clad::array _d_vars(3UL); //CHECK-NEXT: clad::array _d_consts(3UL); -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; //CHECK-NEXT: double vars[3] = {x, y, z}; //CHECK-NEXT: double consts[3] = {1, 2, 3}; -//CHECK-NEXT: _t1 = vars[0]; -//CHECK-NEXT: _t0 = consts[0]; -//CHECK-NEXT: _t3 = vars[1]; -//CHECK-NEXT: _t2 = consts[1]; -//CHECK-NEXT: _t5 = vars[2]; -//CHECK-NEXT: _t4 = consts[2]; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * consts[0]; //CHECK-NEXT: _d_vars[0] += _r0; -//CHECK-NEXT: double _r1 = _t1 * 1; +//CHECK-NEXT: double _r1 = vars[0] * 1; //CHECK-NEXT: _d_consts[0] += _r1; -//CHECK-NEXT: double _r2 = 1 * _t2; +//CHECK-NEXT: double _r2 = 1 * consts[1]; //CHECK-NEXT: _d_vars[1] += _r2; -//CHECK-NEXT: double _r3 = _t3 * 1; +//CHECK-NEXT: double _r3 = vars[1] * 1; //CHECK-NEXT: _d_consts[1] += _r3; -//CHECK-NEXT: double _r4 = 1 * _t4; +//CHECK-NEXT: double _r4 = 1 * consts[2]; //CHECK-NEXT: _d_vars[2] += _r4; -//CHECK-NEXT: double _r5 = _t5 * 1; +//CHECK-NEXT: double _r5 = vars[2] * 1; //CHECK-NEXT: _d_consts[2] += _r5; //CHECK-NEXT: } //CHECK-NEXT: { diff --git a/test/CUDA/GradientCuda.cu b/test/CUDA/GradientCuda.cu index b855bc56c..1d13c2f42 100644 --- a/test/CUDA/GradientCuda.cu +++ b/test/CUDA/GradientCuda.cu @@ -35,92 +35,72 @@ auto gauss_g = clad::gradient(gauss, "p"); //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t2 = {}; -//CHECK-NEXT: clad::tape _t4 = {}; -//CHECK-NEXT: clad::tape _t6 = {}; -//CHECK-NEXT: clad::tape _t7 = {}; -//CHECK-NEXT: clad::tape _t9 = {}; -//CHECK-NEXT: double _t11; -//CHECK-NEXT: double _t12; -//CHECK-NEXT: double _t13; -//CHECK-NEXT: double _t14; -//CHECK-NEXT: double _t15; -//CHECK-NEXT: double _t16; -//CHECK-NEXT: double _t17; -//CHECK-NEXT: double _t18; -//CHECK-NEXT: double _t19; -//CHECK-NEXT: double _t20; -//CHECK-NEXT: double _t21; -//CHECK-NEXT: double _t22; -//CHECK-NEXT: double _t23; +//CHECK-NEXT: double _t2; +//CHECK-NEXT: double _t3; +//CHECK-NEXT: double _t4; +//CHECK-NEXT: double _t5; +//CHECK-NEXT: double _t6; //CHECK-NEXT: double t = 0; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < dim; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: t += clad::push(_t6, (x[clad::push(_t2, i)] - p[clad::push(_t4, i)])) * clad::push(_t1, (x[clad::push(_t7, i)] - p[clad::push(_t9, i)])); +//CHECK-NEXT: clad::push(_t1, t); +//CHECK-NEXT: t += (x[i] - p[i]) * (x[i] - p[i]); //CHECK-NEXT: } -//CHECK-NEXT: _t12 = -t; -//CHECK-NEXT: _t14 = sigma; -//CHECK-NEXT: _t15 = 2 * _t14; -//CHECK-NEXT: _t13 = sigma; -//CHECK-NEXT: _t11 = (_t15 * _t13); -//CHECK-NEXT: t = _t12 / _t11; -//CHECK-NEXT: _t18 = 2 * 3.1415926535897931; -//CHECK-NEXT: _t19 = -dim / 2.; -//CHECK-NEXT: _t20 = std::pow(_t18, _t19); -//CHECK-NEXT: _t21 = sigma; -//CHECK-NEXT: _t17 = std::pow(_t21, -0.5); -//CHECK-NEXT: _t22 = _t20 * _t17; -//CHECK-NEXT: _t23 = t; -//CHECK-NEXT: _t16 = std::exp(_t23); +//CHECK-NEXT: _t2 = t; +//CHECK-NEXT: _t3 = (2 * sigma * sigma); +//CHECK-NEXT: t = -t / _t3; +//CHECK-NEXT: _t6 = 2.; +//CHECK-NEXT: _t5 = std::pow(sigma, -0.5); +//CHECK-NEXT: _t4 = std::exp(t); //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r8 = 1 * _t16; -//CHECK-NEXT: double _r9 = _r8 * _t17; +//CHECK-NEXT: double _r8 = 1 * _t4; +//CHECK-NEXT: double _r9 = _r8 * _t5; //CHECK-NEXT: double _grad0 = 0.; //CHECK-NEXT: double _grad1 = 0.; -//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(_t18, _t19, _r9, &_grad0, &_grad1); +//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(2 * 3.1415926535897931, -dim / _t6, _r9, &_grad0, &_grad1); //CHECK-NEXT: double _r10 = _grad0; //CHECK-NEXT: double _r11 = _r10 * 3.1415926535897931; //CHECK-NEXT: double _r12 = _grad1; -//CHECK-NEXT: double _r13 = _r12 / 2.; +//CHECK-NEXT: double _r13 = _r12 / _t6; //CHECK-NEXT: _d_dim += -_r13; -//CHECK-NEXT: double _r14 = _t20 * _r8; +//CHECK-NEXT: double _r14 = _r12 * --dim / (_t6 * _t6); +//CHECK-NEXT: double _r15 = std::pow(2 * 3.1415926535897931, -dim / _t6) * _r8; //CHECK-NEXT: double _grad2 = 0.; //CHECK-NEXT: double _grad3 = 0.; -//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(_t21, -0.5, _r14, &_grad2, &_grad3); -//CHECK-NEXT: double _r15 = _grad2; -//CHECK-NEXT: _d_sigma += _r15; -//CHECK-NEXT: double _r16 = _grad3; -//CHECK-NEXT: double _r17 = _t22 * 1; -//CHECK-NEXT: double _r18 = _r17 * clad::custom_derivatives::exp_pushforward(_t23, 1.).pushforward; -//CHECK-NEXT: _d_t += _r18; +//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(sigma, -0.5, _r15, &_grad2, &_grad3); +//CHECK-NEXT: double _r16 = _grad2; +//CHECK-NEXT: _d_sigma += _r16; +//CHECK-NEXT: double _r17 = _grad3; +//CHECK-NEXT: double _r18 = std::pow(2 * 3.1415926535897931, -dim / _t6) * _t5 * 1; +//CHECK-NEXT: double _r19 = _r18 * clad::custom_derivatives::exp_pushforward(t, 1.).pushforward; +//CHECK-NEXT: _d_t += _r19; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: t = _t2; //CHECK-NEXT: double _r_d1 = _d_t; -//CHECK-NEXT: double _r2 = _r_d1 / _t11; +//CHECK-NEXT: double _r2 = _r_d1 / _t3; //CHECK-NEXT: _d_t += -_r2; -//CHECK-NEXT: double _r3 = _r_d1 * -_t12 / (_t11 * _t11); -//CHECK-NEXT: double _r4 = _r3 * _t13; -//CHECK-NEXT: double _r5 = _r4 * _t14; +//CHECK-NEXT: double _r3 = _r_d1 * --t / (_t3 * _t3); +//CHECK-NEXT: double _r4 = _r3 * sigma; +//CHECK-NEXT: double _r5 = _r4 * sigma; //CHECK-NEXT: double _r6 = 2 * _r4; //CHECK-NEXT: _d_sigma += _r6; -//CHECK-NEXT: double _r7 = _t15 * _r3; +//CHECK-NEXT: double _r7 = 2 * sigma * _r3; //CHECK-NEXT: _d_sigma += _r7; //CHECK-NEXT: _d_t -= _r_d1; //CHECK-NEXT: } //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; +//CHECK-NEXT: t = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_t; //CHECK-NEXT: _d_t += _r_d0; -//CHECK-NEXT: double _r0 = _r_d0 * clad::pop(_t1); -//CHECK-NEXT: int _t3 = clad::pop(_t2); -//CHECK-NEXT: int _t5 = clad::pop(_t4); -//CHECK-NEXT: _d_p[_t5] += -_r0; -//CHECK-NEXT: double _r1 = clad::pop(_t6) * _r_d0; -//CHECK-NEXT: int _t8 = clad::pop(_t7); -//CHECK-NEXT: int _t10 = clad::pop(_t9); -//CHECK-NEXT: _d_p[_t10] += -_r1; +//CHECK-NEXT: double _r0 = _r_d0 * (x[i] - p[i]); +//CHECK-NEXT: _d_p[i] += -_r0; +//CHECK-NEXT: double _r1 = (x[i] - p[i]) * _r_d0; +//CHECK-NEXT: _d_p[i] += -_r1; //CHECK-NEXT: _d_t -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: } diff --git a/test/Enzyme/DifferentCladEnzymeDerivatives.C b/test/Enzyme/DifferentCladEnzymeDerivatives.C index c3cd617dd..75289831b 100644 --- a/test/Enzyme/DifferentCladEnzymeDerivatives.C +++ b/test/Enzyme/DifferentCladEnzymeDerivatives.C @@ -11,16 +11,12 @@ double foo(double x, double y){ } // CHECK: void foo_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: _t1 = x; -// CHECK-NEXT: _t0 = y; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; +// CHECK-NEXT: double _r0 = 1 * y; // CHECK-NEXT: * _d_x += _r0; -// CHECK-NEXT: double _r1 = _t1 * 1; +// CHECK-NEXT: double _r1 = x * 1; // CHECK-NEXT: * _d_y += _r1; // CHECK-NEXT: } // CHECK-NEXT: } @@ -32,6 +28,6 @@ double foo(double x, double y){ // CHECK-NEXT: } int main(){ - auto grad = clad::gradient(foo); + auto grad = clad::gradient(foo); auto gradEnzyme = clad::gradient(foo); -} \ No newline at end of file +} diff --git a/test/Enzyme/LoopsReverseModeComparisonWithClad.C b/test/Enzyme/LoopsReverseModeComparisonWithClad.C index 73a3e94ec..3de7775ba 100644 --- a/test/Enzyme/LoopsReverseModeComparisonWithClad.C +++ b/test/Enzyme/LoopsReverseModeComparisonWithClad.C @@ -92,7 +92,7 @@ double f6 (double i, double j) { double fn7(double i, double j) { double a = 0; int counter = 3; - while (counter--) + while (counter--) a += i*i + j; return a; } @@ -229,7 +229,7 @@ double fn13(double i, double j) { double fn14(double i, double j) { int choice = 5; double res = 0; - for (int counter=0; counter _d_x, clad::array_ref _d_y, double &_final_error) { +//CHECK-NEXT: float _t0; //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: float _EERepl_x0 = x; //CHECK-NEXT: float _EERepl_x1; +//CHECK-NEXT: float _t1; +//CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = x + y; //CHECK-NEXT: _EERepl_x1 = x; +//CHECK-NEXT: _t1 = y; //CHECK-NEXT: y = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_y += 1; //CHECK-NEXT: { +//CHECK-NEXT: y = _t1; //CHECK-NEXT: float _r_d1 = * _d_y; //CHECK-NEXT: * _d_x += _r_d1; //CHECK-NEXT: * _d_y -= _r_d1; //CHECK-NEXT: * _d_y; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_y += _r_d0; @@ -48,31 +54,26 @@ float func2(float x, int y) { } //CHECK: void func2_grad(float x, int y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { +//CHECK-NEXT: float _t0; //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _t0; -//CHECK-NEXT: int _t1; -//CHECK-NEXT: float _t2; -//CHECK-NEXT: float _t3; //CHECK-NEXT: float _EERepl_x1; -//CHECK-NEXT: _t1 = y; //CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t3 = x; -//CHECK-NEXT: _t2 = x; -//CHECK-NEXT: x = _t1 * _t0 + _t3 * _t2; +//CHECK-NEXT: x = y * x + x * x; //CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_x += 1; //CHECK-NEXT: { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; -//CHECK-NEXT: float _r0 = _r_d0 * _t0; +//CHECK-NEXT: float _r0 = _r_d0 * x; //CHECK-NEXT: * _d_y += _r0; -//CHECK-NEXT: float _r1 = _t1 * _r_d0; +//CHECK-NEXT: float _r1 = y * _r_d0; //CHECK-NEXT: * _d_x += _r1; -//CHECK-NEXT: float _r2 = _r_d0 * _t2; +//CHECK-NEXT: float _r2 = _r_d0 * x; //CHECK-NEXT: * _d_x += _r2; -//CHECK-NEXT: float _r3 = _t3 * _r_d0; +//CHECK-NEXT: float _r3 = x * _r_d0; //CHECK-NEXT: * _d_x += _r3; //CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x -= _r_d0; @@ -88,11 +89,14 @@ float func3(int x, int y) { } //CHECK: void func3_grad(int x, int y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { +//CHECK-NEXT: int _t0; +//CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_y += 1; //CHECK-NEXT: { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: int _r_d0 = * _d_x; //CHECK-NEXT: * _d_y += _r_d0; //CHECK-NEXT: * _d_x -= _r_d0; @@ -110,17 +114,20 @@ float func4(float x, float y) { //CHECK-NEXT: double _d_z = 0; //CHECK-NEXT: double _delta_z = 0; //CHECK-NEXT: double _EERepl_z0; +//CHECK-NEXT: float _t0; //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: float _EERepl_x0 = x; //CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: double z = y; //CHECK-NEXT: _EERepl_z0 = z; +//CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = z + y; //CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_x += 1; //CHECK-NEXT: { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: _d_z += _r_d0; //CHECK-NEXT: * _d_y += _r_d0; @@ -143,16 +150,19 @@ float func5(float x, float y) { //CHECK: void func5_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: int _d_z = 0; +//CHECK-NEXT: float _t0; //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: float _EERepl_x0 = x; //CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: int z = 56; +//CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = z + y; //CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_x += 1; //CHECK-NEXT: { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: _d_z += _r_d0; //CHECK-NEXT: * _d_y += _r_d0; @@ -180,18 +190,14 @@ float func6(float x) { return x; } float func7(float x, float y) { return (x * y); } //CHECK: void func7_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; //CHECK-NEXT: double _ret_value0 = 0; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = y; -//CHECK-NEXT: _ret_value0 = (_t1 * _t0); +//CHECK-NEXT: _ret_value0 = (x * y); //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: float _r0 = 1 * _t0; +//CHECK-NEXT: float _r0 = 1 * y; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: float _r1 = _t1 * 1; +//CHECK-NEXT: float _r1 = x * 1; //CHECK-NEXT: * _d_y += _r1; //CHECK-NEXT: } //CHECK-NEXT: double _delta_x = 0; diff --git a/test/ErrorEstimation/BasicOps.C b/test/ErrorEstimation/BasicOps.C index 64057c056..fbcd74492 100644 --- a/test/ErrorEstimation/BasicOps.C +++ b/test/ErrorEstimation/BasicOps.C @@ -14,41 +14,43 @@ float func(float x, float y) { } //CHECK: void func_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { +//CHECK-NEXT: float _t0; //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: float _EERepl_x0 = x; //CHECK-NEXT: float _EERepl_x1; +//CHECK-NEXT: float _t1; //CHECK-NEXT: double _delta_y = 0; //CHECK-NEXT: float _EERepl_y0 = y; //CHECK-NEXT: float _EERepl_y1; //CHECK-NEXT: float _EERepl_y2; -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; //CHECK-NEXT: float _d_z = 0; //CHECK-NEXT: double _delta_z = 0; //CHECK-NEXT: float _EERepl_z0; +//CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = x + y; //CHECK-NEXT: _EERepl_x1 = x; +//CHECK-NEXT: _t1 = y; //CHECK-NEXT: _EERepl_y1 = y; //CHECK-NEXT: y = y + y++ + y; //CHECK-NEXT: _EERepl_y2 = y; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: float z = _t1 * _t0; +//CHECK-NEXT: float z = y * x; //CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_z += 1; //CHECK-NEXT: { -//CHECK-NEXT: float _r0 = _d_z * _t0; +//CHECK-NEXT: float _r0 = _d_z * x; //CHECK-NEXT: * _d_y += _r0; -//CHECK-NEXT: float _r1 = _t1 * _d_z; +//CHECK-NEXT: float _r1 = y * _d_z; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: _delta_z += std::abs(_d_z * _EERepl_z0 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: y = _t1; //CHECK-NEXT: float _r_d1 = * _d_y; //CHECK-NEXT: * _d_y += _r_d1; //CHECK-NEXT: * _d_y += _r_d1; +//CHECK-NEXT: y--; //CHECK-NEXT: _delta_y += std::abs(* _d_y * _EERepl_y1 * {{.+}}); //CHECK-NEXT: * _d_y += _r_d1; //CHECK-NEXT: _delta_y += std::abs(_r_d1 * _EERepl_y2 * {{.+}}); @@ -56,6 +58,7 @@ float func(float x, float y) { //CHECK-NEXT: * _d_y; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_y += _r_d0; @@ -77,41 +80,38 @@ float func2(float x, float y) { } //CHECK: void func2_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { +//CHECK-NEXT: float _t0; //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; //CHECK-NEXT: float _EERepl_x1; -//CHECK-NEXT: float _t2; -//CHECK-NEXT: float _t3; +//CHECK-NEXT: float _t1; //CHECK-NEXT: float _d_z = 0; //CHECK-NEXT: double _delta_z = 0; //CHECK-NEXT: float _EERepl_z0; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t0 = y; -//CHECK-NEXT: x = x - y - _t1 * _t0; +//CHECK-NEXT: _t0 = x; +//CHECK-NEXT: x = x - y - y * y; //CHECK-NEXT: _EERepl_x1 = x; -//CHECK-NEXT: _t3 = y; -//CHECK-NEXT: _t2 = x; -//CHECK-NEXT: float z = _t3 / _t2; +//CHECK-NEXT: _t1 = x; +//CHECK-NEXT: float z = y / _t1; //CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_z += 1; //CHECK-NEXT: { -//CHECK-NEXT: float _r2 = _d_z / _t2; +//CHECK-NEXT: float _r2 = _d_z / _t1; //CHECK-NEXT: * _d_y += _r2; -//CHECK-NEXT: float _r3 = _d_z * -_t3 / (_t2 * _t2); +//CHECK-NEXT: float _r3 = _d_z * -y / (_t1 * _t1); //CHECK-NEXT: * _d_x += _r3; //CHECK-NEXT: _delta_z += std::abs(_d_z * _EERepl_z0 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_y += -_r_d0; -//CHECK-NEXT: float _r0 = -_r_d0 * _t0; +//CHECK-NEXT: float _r0 = -_r_d0 * y; //CHECK-NEXT: * _d_y += _r0; -//CHECK-NEXT: float _r1 = _t1 * -_r_d0; +//CHECK-NEXT: float _r1 = y * -_r_d0; //CHECK-NEXT: * _d_y += _r1; //CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x -= _r_d0; @@ -133,48 +133,43 @@ float func3(float x, float y) { } //CHECK: void func3_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { +//CHECK-NEXT: float _t0; //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: float _EERepl_x0 = x; -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; //CHECK-NEXT: float _EERepl_x1; //CHECK-NEXT: float _d_z = 0; //CHECK-NEXT: double _delta_z = 0; //CHECK-NEXT: float _EERepl_z0; +//CHECK-NEXT: float _t1; //CHECK-NEXT: float _t2; -//CHECK-NEXT: float _t3; -//CHECK-NEXT: float _t4; -//CHECK-NEXT: float _t5; //CHECK-NEXT: double _delta_y = 0; //CHECK-NEXT: float _EERepl_y0 = y; //CHECK-NEXT: float _EERepl_y1; //CHECK-NEXT: float _d_t = 0; //CHECK-NEXT: double _delta_t = 0; //CHECK-NEXT: float _EERepl_t0; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t0 = y; -//CHECK-NEXT: x = x - y - _t1 * _t0; +//CHECK-NEXT: _t0 = x; +//CHECK-NEXT: x = x - y - y * y; //CHECK-NEXT: _EERepl_x1 = x; //CHECK-NEXT: float z = y; //CHECK-NEXT: _EERepl_z0 = z; -//CHECK-NEXT: _t4 = x; -//CHECK-NEXT: _t3 = z; -//CHECK-NEXT: _t5 = _t4 * _t3; -//CHECK-NEXT: _t2 = (y = x + x); -//CHECK-NEXT: float t = _t5 * _t2; +//CHECK-NEXT: _t2 = y; +//CHECK-NEXT: _t1 = (y = x + x); +//CHECK-NEXT: float t = x * z * _t1; //CHECK-NEXT: _EERepl_t0 = t; //CHECK-NEXT: _EERepl_y1 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: { -//CHECK-NEXT: float _r2 = _d_t * _t2; -//CHECK-NEXT: float _r3 = _r2 * _t3; +//CHECK-NEXT: float _r2 = _d_t * _t1; +//CHECK-NEXT: float _r3 = _r2 * z; //CHECK-NEXT: * _d_x += _r3; -//CHECK-NEXT: float _r4 = _t4 * _r2; +//CHECK-NEXT: float _r4 = x * _r2; //CHECK-NEXT: _d_z += _r4; -//CHECK-NEXT: float _r5 = _t5 * _d_t; +//CHECK-NEXT: float _r5 = x * z * _d_t; //CHECK-NEXT: * _d_y += _r5; +//CHECK-NEXT: y = _t2; //CHECK-NEXT: float _r_d1 = * _d_y; //CHECK-NEXT: * _d_x += _r_d1; //CHECK-NEXT: * _d_x += _r_d1; @@ -184,12 +179,13 @@ float func3(float x, float y) { //CHECK-NEXT: } //CHECK-NEXT: * _d_y += _d_z; //CHECK-NEXT: { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_y += -_r_d0; -//CHECK-NEXT: float _r0 = -_r_d0 * _t0; +//CHECK-NEXT: float _r0 = -_r_d0 * y; //CHECK-NEXT: * _d_y += _r0; -//CHECK-NEXT: float _r1 = _t1 * -_r_d0; +//CHECK-NEXT: float _r1 = y * -_r_d0; //CHECK-NEXT: * _d_y += _r1; //CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x -= _r_d0; @@ -204,18 +200,14 @@ float func3(float x, float y) { float func4(float x, float y) { return std::pow(x, y); } //CHECK: void func4_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; //CHECK-NEXT: double _ret_value0 = 0; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _ret_value0 = std::pow(_t0, _t1); +//CHECK-NEXT: _ret_value0 = std::pow(x, y); //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: float _grad0 = 0.F; //CHECK-NEXT: float _grad1 = 0.F; -//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(_t0, _t1, 1, &_grad0, &_grad1); +//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(x, y, 1, &_grad0, &_grad1); //CHECK-NEXT: float _r0 = _grad0; //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: float _r1 = _grad1; @@ -235,30 +227,27 @@ float func5(float x, float y) { } //CHECK: void func5_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { +//CHECK-NEXT: float _t0; //CHECK-NEXT: double _delta_y = 0; //CHECK-NEXT: float _EERepl_y0 = y; -//CHECK-NEXT: float _t0; //CHECK-NEXT: float _EERepl_y1; -//CHECK-NEXT: float _t1; -//CHECK-NEXT: float _t2; //CHECK-NEXT: double _ret_value0 = 0; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: y = std::sin(_t0); +//CHECK-NEXT: _t0 = y; +//CHECK-NEXT: y = std::sin(x); //CHECK-NEXT: _EERepl_y1 = y; -//CHECK-NEXT: _t2 = y; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _ret_value0 = _t2 * _t1; +//CHECK-NEXT: _ret_value0 = y * y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: float _r1 = 1 * _t1; +//CHECK-NEXT: float _r1 = 1 * y; //CHECK-NEXT: * _d_y += _r1; -//CHECK-NEXT: float _r2 = _t2 * 1; +//CHECK-NEXT: float _r2 = y * 1; //CHECK-NEXT: * _d_y += _r2; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: y = _t0; //CHECK-NEXT: float _r_d0 = * _d_y; -//CHECK-NEXT: float _r0 = _r_d0 * clad::custom_derivatives{{(::std)?}}::sin_pushforward(_t0, 1.F).pushforward; +//CHECK-NEXT: float _r0 = _r_d0 * clad::custom_derivatives{{(::std)?}}::sin_pushforward(x, 1.F).pushforward; //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: _delta_y += std::abs(_r_d0 * _EERepl_y1 * {{.+}}); //CHECK-NEXT: * _d_y -= _r_d0; @@ -274,18 +263,14 @@ float func5(float x, float y) { double helper(double x, double y) { return x * y; } //CHECK: void helper_pullback(double x, double y, double _d_y0, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; //CHECK-NEXT: double _ret_value0 = 0; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = y; -//CHECK-NEXT: _ret_value0 = _t1 * _t0; +//CHECK-NEXT: _ret_value0 = x * y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_y0 * _t0; +//CHECK-NEXT: double _r0 = _d_y0 * y; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d_y0; +//CHECK-NEXT: double _r1 = x * _d_y0; //CHECK-NEXT: * _d_y += _r1; //CHECK-NEXT: } //CHECK-NEXT: double _delta_x = 0; @@ -301,39 +286,31 @@ float func6(float x, float y) { } //CHECK: void func6_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; //CHECK-NEXT: float _d_z = 0; //CHECK-NEXT: double _delta_z = 0; //CHECK-NEXT: float _EERepl_z0; -//CHECK-NEXT: float _t3; -//CHECK-NEXT: float _t4; //CHECK-NEXT: double _ret_value0 = 0; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: float z = helper(_t0, _t1); +//CHECK-NEXT: float z = helper(x, y); //CHECK-NEXT: _EERepl_z0 = z; -//CHECK-NEXT: _t4 = z; -//CHECK-NEXT: _t3 = z; -//CHECK-NEXT: _ret_value0 = _t4 * _t3; +//CHECK-NEXT: _ret_value0 = z * z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: float _r2 = 1 * _t3; +//CHECK-NEXT: float _r2 = 1 * z; //CHECK-NEXT: _d_z += _r2; -//CHECK-NEXT: float _r3 = _t4 * 1; +//CHECK-NEXT: float _r3 = z * 1; //CHECK-NEXT: _d_z += _r3; //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: double _grad0 = 0.; //CHECK-NEXT: double _grad1 = 0.; -//CHECK-NEXT: double _t2 = 0; -//CHECK-NEXT: helper_pullback(_t0, _t1, _d_z, &_grad0, &_grad1, _t2); +//CHECK-NEXT: double _t0 = 0; +//CHECK-NEXT: helper_pullback(x, y, _d_z, &_grad0, &_grad1, _t0); //CHECK-NEXT: double _r0 = _grad0; //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: double _r1 = _grad1; //CHECK-NEXT: * _d_y += _r1; -//CHECK-NEXT: _delta_z += _t2; +//CHECK-NEXT: _delta_z += _t0; //CHECK-NEXT: } //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); @@ -366,18 +343,14 @@ float func7(float x) { double helper2(float& x) { return x * x; } //CHECK: void helper2_pullback(float &x, double _d_y, clad::array_ref _d_x, double &_final_error) { -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; //CHECK-NEXT: double _ret_value0 = 0; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _ret_value0 = _t1 * _t0; +//CHECK-NEXT: _ret_value0 = x * x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_y * _t0; +//CHECK-NEXT: double _r0 = _d_y * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d_y; +//CHECK-NEXT: double _r1 = x * _d_y; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: } //CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); @@ -394,23 +367,27 @@ float func8(float x, float y) { //CHECK-NEXT: double _delta_z = 0; //CHECK-NEXT: float _EERepl_z0; //CHECK-NEXT: float _t0; +//CHECK-NEXT: float _t1; //CHECK-NEXT: float _EERepl_z1; //CHECK-NEXT: float z; //CHECK-NEXT: _EERepl_z0 = z; -//CHECK-NEXT: _t0 = x; +//CHECK-NEXT: _t0 = z; +//CHECK-NEXT: _t1 = x; //CHECK-NEXT: z = y + helper2(x); //CHECK-NEXT: _EERepl_z1 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_z += 1; //CHECK-NEXT: { +//CHECK-NEXT: z = _t0; //CHECK-NEXT: float _r_d0 = _d_z; //CHECK-NEXT: * _d_y += _r_d0; -//CHECK-NEXT: double _t1 = 0; -//CHECK-NEXT: helper2_pullback(_t0, _r_d0, &* _d_x, _t1); +//CHECK-NEXT: x = _t1; +//CHECK-NEXT: double _t2 = 0; +//CHECK-NEXT: helper2_pullback(_t1, _r_d0, &* _d_x, _t2); //CHECK-NEXT: float _r0 = * _d_x; -//CHECK-NEXT: _delta_z += _t1; -//CHECK-NEXT: _final_error += std::abs(_r0 * _t0 * {{.+}}); +//CHECK-NEXT: _delta_z += _t2; +//CHECK-NEXT: _final_error += std::abs(_r0 * _t1 * {{.+}}); //CHECK-NEXT: _d_z -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: double _delta_x = 0; @@ -427,61 +404,61 @@ float func9(float x, float y) { } //CHECK: void func9_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { -//CHECK-NEXT: float _t0; //CHECK-NEXT: float _t1; -//CHECK-NEXT: float _t3; //CHECK-NEXT: float _d_z = 0; //CHECK-NEXT: double _delta_z = 0; //CHECK-NEXT: float _EERepl_z0; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: float _t6; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: float _t9; +//CHECK-NEXT: float _t3; +//CHECK-NEXT: double _t4; +//CHECK-NEXT: float _t5; +//CHECK-NEXT: float _t7; //CHECK-NEXT: float _EERepl_z1; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t3 = x; -//CHECK-NEXT: float z = helper(_t0, _t1) + helper2(x); +//CHECK-NEXT: _t1 = x; +//CHECK-NEXT: float z = helper(x, y) + helper2(x); //CHECK-NEXT: _EERepl_z0 = z; -//CHECK-NEXT: _t6 = x; -//CHECK-NEXT: _t8 = helper2(x); -//CHECK-NEXT: _t9 = y; -//CHECK-NEXT: _t5 = helper2(y); -//CHECK-NEXT: z += _t8 * _t5; +//CHECK-NEXT: _t3 = z; +//CHECK-NEXT: _t5 = x; +//CHECK-NEXT: _t7 = y; +//CHECK-NEXT: _t4 = helper2(y); +//CHECK-NEXT: z += helper2(x) * _t4; //CHECK-NEXT: _EERepl_z1 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_z += 1; //CHECK-NEXT: { +//CHECK-NEXT: z = _t3; //CHECK-NEXT: float _r_d0 = _d_z; //CHECK-NEXT: _d_z += _r_d0; -//CHECK-NEXT: double _r3 = _r_d0 * _t5; -//CHECK-NEXT: double _t7 = 0; -//CHECK-NEXT: helper2_pullback(_t6, _r3, &* _d_x, _t7); +//CHECK-NEXT: double _r3 = _r_d0 * _t4; +//CHECK-NEXT: x = _t5; +//CHECK-NEXT: double _t6 = 0; +//CHECK-NEXT: helper2_pullback(_t5, _r3, &* _d_x, _t6); //CHECK-NEXT: float _r4 = * _d_x; -//CHECK-NEXT: double _r5 = _t8 * _r_d0; -//CHECK-NEXT: double _t10 = 0; -//CHECK-NEXT: helper2_pullback(_t9, _r5, &* _d_y, _t10); +//CHECK-NEXT: double _r5 = helper2(x) * _r_d0; +//CHECK-NEXT: y = _t7; +//CHECK-NEXT: double _t8 = 0; +//CHECK-NEXT: helper2_pullback(_t7, _r5, &* _d_y, _t8); //CHECK-NEXT: float _r6 = * _d_y; -//CHECK-NEXT: _delta_z += _t7 + _t10; -//CHECK-NEXT: _final_error += std::abs(_r6 * _t9 * {{.+}}); -//CHECK-NEXT: _final_error += std::abs(_r4 * _t6 * {{.+}}); +//CHECK-NEXT: _delta_z += _t6 + _t8; +//CHECK-NEXT: _final_error += std::abs(_r6 * _t7 * {{.+}}); +//CHECK-NEXT: _final_error += std::abs(_r4 * _t5 * {{.+}}); //CHECK-NEXT: _d_z -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: double _grad0 = 0.; //CHECK-NEXT: double _grad1 = 0.; -//CHECK-NEXT: double _t2 = 0; -//CHECK-NEXT: helper_pullback(_t0, _t1, _d_z, &_grad0, &_grad1, _t2); +//CHECK-NEXT: double _t0 = 0; +//CHECK-NEXT: helper_pullback(x, y, _d_z, &_grad0, &_grad1, _t0); //CHECK-NEXT: double _r0 = _grad0; //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: double _r1 = _grad1; //CHECK-NEXT: * _d_y += _r1; -//CHECK-NEXT: double _t4 = 0; -//CHECK-NEXT: helper2_pullback(_t3, _d_z, &* _d_x, _t4); +//CHECK-NEXT: x = _t1; +//CHECK-NEXT: double _t2 = 0; +//CHECK-NEXT: helper2_pullback(_t1, _d_z, &* _d_x, _t2); //CHECK-NEXT: float _r2 = * _d_x; -//CHECK-NEXT: _delta_z += _t2 + _t4; -//CHECK-NEXT: _final_error += std::abs(_r2 * _t3 * {{.+}}); +//CHECK-NEXT: _delta_z += _t0 + _t2; +//CHECK-NEXT: _final_error += std::abs(_r2 * _t1 * {{.+}}); //CHECK-NEXT: } //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: _delta_x += std::abs(* _d_x * x * {{.+}}); diff --git a/test/ErrorEstimation/ConditonalStatements.C b/test/ErrorEstimation/ConditonalStatements.C index 0b3b3392e..54d5f68ad 100644 --- a/test/ErrorEstimation/ConditonalStatements.C +++ b/test/ErrorEstimation/ConditonalStatements.C @@ -19,31 +19,29 @@ float func(float x, float y) { //CHECK: void func_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: bool _cond0; +//CHECK-NEXT: float _t0; //CHECK-NEXT: double _delta_y = 0; //CHECK-NEXT: float _EERepl_y0 = y; -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; //CHECK-NEXT: float _EERepl_y1; //CHECK-NEXT: float _d_temp = 0; //CHECK-NEXT: double _delta_temp = 0; //CHECK-NEXT: float _EERepl_temp0; -//CHECK-NEXT: float _t2; -//CHECK-NEXT: float _t3; +//CHECK-NEXT: float _t1; //CHECK-NEXT: float _EERepl_temp1; +//CHECK-NEXT: float _t2; //CHECK-NEXT: double _ret_value0 = 0; //CHECK-NEXT: _cond0 = x > y; //CHECK-NEXT: if (_cond0) { -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: y = _t1 * _t0; +//CHECK-NEXT: _t0 = y; +//CHECK-NEXT: y = y * x; //CHECK-NEXT: _EERepl_y1 = y; //CHECK-NEXT: } else { //CHECK-NEXT: float temp = y; //CHECK-NEXT: _EERepl_temp0 = temp; -//CHECK-NEXT: _t3 = y; -//CHECK-NEXT: _t2 = y; -//CHECK-NEXT: temp = _t3 * _t2; +//CHECK-NEXT: _t1 = temp; +//CHECK-NEXT: temp = y * y; //CHECK-NEXT: _EERepl_temp1 = temp; +//CHECK-NEXT: _t2 = x; //CHECK-NEXT: x = y; //CHECK-NEXT: } //CHECK-NEXT: _ret_value0 = x + y; @@ -55,10 +53,11 @@ float func(float x, float y) { //CHECK-NEXT: } //CHECK-NEXT: if (_cond0) { //CHECK-NEXT: { +//CHECK-NEXT: y = _t0; //CHECK-NEXT: float _r_d0 = * _d_y; -//CHECK-NEXT: float _r0 = _r_d0 * _t0; +//CHECK-NEXT: float _r0 = _r_d0 * x; //CHECK-NEXT: * _d_y += _r0; -//CHECK-NEXT: float _r1 = _t1 * _r_d0; +//CHECK-NEXT: float _r1 = y * _r_d0; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: _delta_y += std::abs(_r_d0 * _EERepl_y1 * {{.+}}); //CHECK-NEXT: * _d_y -= _r_d0; @@ -66,16 +65,18 @@ float func(float x, float y) { //CHECK-NEXT: } //CHECK-NEXT: } else { //CHECK-NEXT: { +//CHECK-NEXT: x = _t2; //CHECK-NEXT: float _r_d2 = * _d_x; //CHECK-NEXT: * _d_y += _r_d2; //CHECK-NEXT: * _d_x -= _r_d2; //CHECK-NEXT: * _d_x; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: temp = _t1; //CHECK-NEXT: float _r_d1 = _d_temp; -//CHECK-NEXT: float _r2 = _r_d1 * _t2; +//CHECK-NEXT: float _r2 = _r_d1 * y; //CHECK-NEXT: * _d_y += _r2; -//CHECK-NEXT: float _r3 = _t3 * _r_d1; +//CHECK-NEXT: float _r3 = y * _r_d1; //CHECK-NEXT: * _d_y += _r3; //CHECK-NEXT: _delta_temp += std::abs(_r_d1 * _EERepl_temp1 * {{.+}}); //CHECK-NEXT: _d_temp -= _r_d1; @@ -98,27 +99,19 @@ float func2(float x) { } //CHECK: void func2_grad(float x, clad::array_ref _d_x, double &_final_error) { -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; //CHECK-NEXT: float _d_z = 0; //CHECK-NEXT: double _delta_z = 0; //CHECK-NEXT: float _EERepl_z0; //CHECK-NEXT: bool _cond0; //CHECK-NEXT: double _ret_value0 = 0; -//CHECK-NEXT: float _t2; -//CHECK-NEXT: float _t3; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: float z = _t1 * _t0; +//CHECK-NEXT: float z = x * x; //CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: _cond0 = z > 9; //CHECK-NEXT: if (_cond0) { //CHECK-NEXT: _ret_value0 = x + x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: } else { -//CHECK-NEXT: _t3 = x; -//CHECK-NEXT: _t2 = x; -//CHECK-NEXT: _ret_value0 = _t3 * _t2; +//CHECK-NEXT: _ret_value0 = x * x; //CHECK-NEXT: goto _label1; //CHECK-NEXT: } //CHECK-NEXT: if (_cond0) @@ -130,15 +123,15 @@ float func2(float x) { //CHECK-NEXT: else //CHECK-NEXT: _label1: //CHECK-NEXT: { -//CHECK-NEXT: float _r2 = 1 * _t2; +//CHECK-NEXT: float _r2 = 1 * x; //CHECK-NEXT: * _d_x += _r2; -//CHECK-NEXT: float _r3 = _t3 * 1; +//CHECK-NEXT: float _r3 = x * 1; //CHECK-NEXT: * _d_x += _r3; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: float _r0 = _d_z * _t0; +//CHECK-NEXT: float _r0 = _d_z * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: float _r1 = _t1 * _d_z; +//CHECK-NEXT: float _r1 = x * _d_z; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: _delta_z += std::abs(_d_z * _EERepl_z0 * {{.+}}); //CHECK-NEXT: } @@ -151,21 +144,15 @@ float func3(float x, float y) { return x > 30 ? x * y : x + y; } //CHECK: void func3_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: bool _cond0; -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; //CHECK-NEXT: double _ret_value0 = 0; //CHECK-NEXT: _cond0 = x > 30; -//CHECK-NEXT: if (_cond0) { -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = y; -//CHECK-NEXT: } -//CHECK-NEXT: _ret_value0 = _cond0 ? _t1 * _t0 : x + y; +//CHECK-NEXT: _ret_value0 = _cond0 ? x * y : x + y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: if (_cond0) { -//CHECK-NEXT: float _r0 = 1 * _t0; +//CHECK-NEXT: float _r0 = 1 * y; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: float _r1 = _t1 * 1; +//CHECK-NEXT: float _r1 = x * 1; //CHECK-NEXT: * _d_y += _r1; //CHECK-NEXT: } else { //CHECK-NEXT: * _d_x += 1; @@ -185,46 +172,44 @@ float func4(float x, float y) { //CHECK: void func4_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: bool _cond0; +//CHECK-NEXT: float _t0; //CHECK-NEXT: double _delta_x = 0; //CHECK-NEXT: float _EERepl_x0 = x; //CHECK-NEXT: float _EERepl_x1; -//CHECK-NEXT: float _t0; //CHECK-NEXT: float _t1; //CHECK-NEXT: float _EERepl_x2; //CHECK-NEXT: float _t2; -//CHECK-NEXT: float _t3; //CHECK-NEXT: double _ret_value0 = 0; //CHECK-NEXT: _cond0 = !x; //CHECK-NEXT: if (_cond0) -//CHECK-NEXT: ; -//CHECK-NEXT: else { -//CHECK-NEXT: _t1 = x; //CHECK-NEXT: _t0 = x; -//CHECK-NEXT: } -//CHECK-NEXT: _cond0 ? (x += 1) : (x *= _t0); +//CHECK-NEXT: else +//CHECK-NEXT: _t1 = x; +//CHECK-NEXT: _cond0 ? (x += 1) : (x *= x); //CHECK-NEXT: _EERepl_x2 = x; //CHECK-NEXT: _EERepl_x1 = x; -//CHECK-NEXT: _t3 = y; //CHECK-NEXT: _t2 = x; -//CHECK-NEXT: _ret_value0 = _t3 / _t2; +//CHECK-NEXT: _ret_value0 = y / _t2; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: float _r1 = 1 / _t2; //CHECK-NEXT: * _d_y += _r1; -//CHECK-NEXT: float _r2 = 1 * -_t3 / (_t2 * _t2); +//CHECK-NEXT: float _r2 = 1 * -y / (_t2 * _t2); //CHECK-NEXT: * _d_x += _r2; //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: if (_cond0) { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: float _r_d0 = * _d_x; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: _delta_x += std::abs(_r_d0 * _EERepl_x1 * {{.+}}); //CHECK-NEXT: * _d_x -= _r_d0; //CHECK-NEXT: } else { +//CHECK-NEXT: x = _t1; //CHECK-NEXT: float _r_d1 = * _d_x; -//CHECK-NEXT: * _d_x += _r_d1 * _t0; -//CHECK-NEXT: float _r0 = _t1 * _r_d1; +//CHECK-NEXT: * _d_x += _r_d1 * x; +//CHECK-NEXT: float _r0 = x * _r_d1; //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: _delta_x += std::abs(_r_d1 * _EERepl_x2 * {{.+}}); //CHECK-NEXT: * _d_x -= _r_d1; diff --git a/test/ErrorEstimation/LoopsAndArrays.C b/test/ErrorEstimation/LoopsAndArrays.C index db6d329fd..aef6736a5 100644 --- a/test/ErrorEstimation/LoopsAndArrays.C +++ b/test/ErrorEstimation/LoopsAndArrays.C @@ -20,25 +20,27 @@ float func(float* p, int n) { //CHECK-NEXT: float _EERepl_sum0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: float sum = 0; //CHECK-NEXT: _EERepl_sum0 = sum; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < n; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: sum += p[clad::push(_t1, i)]; +//CHECK-NEXT: clad::push(_t1, sum); +//CHECK-NEXT: sum += p[i]; //CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: float _r_d0 = _d_sum; //CHECK-NEXT: _d_sum += _r_d0; -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: _d_p[_t2] += _r_d0; +//CHECK-NEXT: _d_p[i] += _r_d0; //CHECK-NEXT: float _r0 = clad::pop(_EERepl_sum1); //CHECK-NEXT: _delta_sum += std::abs(_r_d0 * _r0 * {{.+}}); //CHECK-NEXT: _d_sum -= _r_d0; @@ -48,9 +50,9 @@ float func(float* p, int n) { //CHECK-NEXT: clad::array _delta_p(_d_p.size()); //CHECK-NEXT: int i = 0; //CHECK-NEXT: for (; i < _d_p.size(); i++) { -//CHECK-NEXT: double _t3 = std::abs(_d_p[i] * p[i] * {{.+}}); -//CHECK-NEXT: _delta_p[i] += _t3; -//CHECK-NEXT: _final_error += _t3; +//CHECK-NEXT: double _t2 = std::abs(_d_p[i] * p[i] * {{.+}}); +//CHECK-NEXT: _delta_p[i] += _t2; +//CHECK-NEXT: _final_error += _t2; //CHECK-NEXT: } //CHECK-NEXT: _final_error += _delta_sum; //CHECK-NEXT: } @@ -72,18 +74,20 @@ float func2(float x) { //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: float _d_m = 0; //CHECK-NEXT: double _delta_m = 0; //CHECK-NEXT: clad::tape _EERepl_m0 = {}; +//CHECK-NEXT: float m = 0; +//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: clad::tape _EERepl_z1 = {}; //CHECK-NEXT: float z; //CHECK-NEXT: _EERepl_z0 = z; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < 9; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: float m = clad::push(_t2, x) * clad::push(_t1, x); +//CHECK-NEXT: clad::push(_t1, m) , m = x * x; //CHECK-NEXT: clad::push(_EERepl_m0, m); +//CHECK-NEXT: clad::push(_t2, z); //CHECK-NEXT: z = m + m; //CHECK-NEXT: clad::push(_EERepl_z1, z); //CHECK-NEXT: } @@ -91,7 +95,9 @@ float func2(float x) { //CHECK-NEXT: _label0: //CHECK-NEXT: _d_z += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: z = clad::pop(_t2); //CHECK-NEXT: float _r_d0 = _d_z; //CHECK-NEXT: _d_m += _r_d0; //CHECK-NEXT: _d_m += _r_d0; @@ -100,11 +106,12 @@ float func2(float x) { //CHECK-NEXT: _d_z -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: float _r0 = _d_m * clad::pop(_t1); +//CHECK-NEXT: float _r0 = _d_m * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: float _r1 = clad::pop(_t2) * _d_m; +//CHECK-NEXT: float _r1 = x * _d_m; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: _d_m = 0; +//CHECK-NEXT: m = clad::pop(_t1); //CHECK-NEXT: float _r2 = clad::pop(_EERepl_m0); //CHECK-NEXT: _delta_m += std::abs(_d_m * _r2 * {{.+}}); //CHECK-NEXT: } @@ -125,24 +132,27 @@ float func3(float x, float y) { //CHECK: void func3_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y, double &_final_error) { //CHECK-NEXT: clad::array _d_arr(3UL); //CHECK-NEXT: clad::array _delta_arr(_d_arr.size()); +//CHECK-NEXT: double _t0; //CHECK-NEXT: double _EERepl_arr0; -//CHECK-NEXT: float _t0; -//CHECK-NEXT: float _t1; +//CHECK-NEXT: double _t1; //CHECK-NEXT: double _EERepl_arr1; +//CHECK-NEXT: double _t2; //CHECK-NEXT: double _EERepl_arr2; //CHECK-NEXT: double arr[3]; +//CHECK-NEXT: _t0 = arr[0]; //CHECK-NEXT: arr[0] = x + y; //CHECK-NEXT: _EERepl_arr0 = arr[0]; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: arr[1] = _t1 * _t0; +//CHECK-NEXT: _t1 = arr[1]; +//CHECK-NEXT: arr[1] = x * x; //CHECK-NEXT: _EERepl_arr1 = arr[1]; +//CHECK-NEXT: _t2 = arr[2]; //CHECK-NEXT: arr[2] = arr[0] + arr[1]; //CHECK-NEXT: _EERepl_arr2 = arr[2]; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_arr[2] += 1; //CHECK-NEXT: { +//CHECK-NEXT: arr[2] = _t2; //CHECK-NEXT: double _r_d2 = _d_arr[2]; //CHECK-NEXT: _d_arr[0] += _r_d2; //CHECK-NEXT: _d_arr[1] += _r_d2; @@ -152,10 +162,11 @@ float func3(float x, float y) { //CHECK-NEXT: _d_arr[2]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: arr[1] = _t1; //CHECK-NEXT: double _r_d1 = _d_arr[1]; -//CHECK-NEXT: double _r0 = _r_d1 * _t0; +//CHECK-NEXT: double _r0 = _r_d1 * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _r_d1; +//CHECK-NEXT: double _r1 = x * _r_d1; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: _delta_arr[1] += std::abs(_r_d1 * _EERepl_arr1 * {{.+}}); //CHECK-NEXT: _final_error += _delta_arr[1]; @@ -163,6 +174,7 @@ float func3(float x, float y) { //CHECK-NEXT: _d_arr[1]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: arr[0] = _t0; //CHECK-NEXT: double _r_d0 = _d_arr[0]; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_y += _r_d0; @@ -193,66 +205,66 @@ float func4(float x[10], float y[10]) { //CHECK-NEXT: float _EERepl_sum0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: clad::array _delta_x(_d_x.size()); //CHECK-NEXT: clad::array _EERepl_x0(_d_x.size()); //CHECK-NEXT: for (int i0 = 0; i0 < _d_x.size(); i0++) { //CHECK-NEXT: _EERepl_x0[i0] = x[i0]; //CHECK-NEXT: } -//CHECK-NEXT: clad::tape _t3 = {}; //CHECK-NEXT: clad::tape _EERepl_x1 = {}; -//CHECK-NEXT: clad::tape _t5 = {}; +//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: float sum = 0; //CHECK-NEXT: _EERepl_sum0 = sum; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < 10; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: x[clad::push(_t1, i)] += y[clad::push(_t3, i)]; -//CHECK-NEXT: clad::push(_EERepl_x1, x[clad::push(_t1, i)]); -//CHECK-NEXT: sum += x[clad::push(_t5, i)]; +//CHECK-NEXT: clad::push(_t1, x[i]); +//CHECK-NEXT: x[i] += y[i]; +//CHECK-NEXT: clad::push(_EERepl_x1, x[i]); +//CHECK-NEXT: clad::push(_t2, sum); +//CHECK-NEXT: sum += x[i]; //CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: sum = clad::pop(_t2); //CHECK-NEXT: float _r_d1 = _d_sum; //CHECK-NEXT: _d_sum += _r_d1; -//CHECK-NEXT: int _t6 = clad::pop(_t5); -//CHECK-NEXT: _d_x[_t6] += _r_d1; -//CHECK-NEXT: float _r2 = clad::pop(_EERepl_sum1); -//CHECK-NEXT: _delta_sum += std::abs(_r_d1 * _r2 * {{.+}}); +//CHECK-NEXT: _d_x[i] += _r_d1; +//CHECK-NEXT: float _r1 = clad::pop(_EERepl_sum1); +//CHECK-NEXT: _delta_sum += std::abs(_r_d1 * _r1 * {{.+}}); //CHECK-NEXT: _d_sum -= _r_d1; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: float _r_d0 = _d_x[_t2]; -//CHECK-NEXT: _d_x[_t2] += _r_d0; -//CHECK-NEXT: int _t4 = clad::pop(_t3); -//CHECK-NEXT: _d_y[_t4] += _r_d0; +//CHECK-NEXT: x[i] = clad::pop(_t1); +//CHECK-NEXT: float _r_d0 = _d_x[i]; +//CHECK-NEXT: _d_x[i] += _r_d0; +//CHECK-NEXT: _d_y[i] += _r_d0; //CHECK-NEXT: float _r0 = clad::pop(_EERepl_x1); -//CHECK-NEXT: int _r1 = clad::pop(_t1); -//CHECK-NEXT: _delta_x[_r1] += std::abs(_r_d0 * _r0 * {{.+}}); -//CHECK-NEXT: _final_error += _delta_x[_r1]; -//CHECK-NEXT: _d_x[_t2] -= _r_d0; -//CHECK-NEXT: _d_x[_t2]; +//CHECK-NEXT: _delta_x[i] += std::abs(_r_d0 * _r0 * {{.+}}); +//CHECK-NEXT: _final_error += _delta_x[i]; +//CHECK-NEXT: _d_x[i] -= _r_d0; +//CHECK-NEXT: _d_x[i]; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: _delta_sum += std::abs(_d_sum * _EERepl_sum0 * {{.+}}); //CHECK-NEXT: int i = 0; //CHECK-NEXT: for (; i < _d_x.size(); i++) { -//CHECK-NEXT: double _t7 = std::abs(_d_x[i] * _EERepl_x0[i] * {{.+}}); -//CHECK-NEXT: _delta_x[i] += _t7; -//CHECK-NEXT: _final_error += _t7; +//CHECK-NEXT: double _t3 = std::abs(_d_x[i] * _EERepl_x0[i] * {{.+}}); +//CHECK-NEXT: _delta_x[i] += _t3; +//CHECK-NEXT: _final_error += _t3; //CHECK-NEXT: } //CHECK-NEXT: clad::array _delta_y(_d_y.size()); //CHECK-NEXT: i = 0; //CHECK-NEXT: for (; i < _d_y.size(); i++) { -//CHECK-NEXT: double _t8 = std::abs(_d_y[i] * y[i] * {{.+}}); -//CHECK-NEXT: _delta_y[i] += _t8; -//CHECK-NEXT: _final_error += _t8; +//CHECK-NEXT: double _t4 = std::abs(_d_y[i] * y[i] * {{.+}}); +//CHECK-NEXT: _delta_y[i] += _t4; +//CHECK-NEXT: _final_error += _t4; //CHECK-NEXT: } //CHECK-NEXT: _final_error += _delta_sum; //CHECK-NEXT: } @@ -266,44 +278,26 @@ double func5(double* x, double* y, double* output) { } //CHECK: void func5_grad(double *x, double *y, double *output, clad::array_ref _d_x, clad::array_ref _d_y, clad::array_ref _d_output, double &_final_error) { +//CHECK-NEXT: double _t0; //CHECK-NEXT: clad::array _delta_output(_d_output.size()); //CHECK-NEXT: clad::array _EERepl_output0(_d_output.size()); //CHECK-NEXT: for (int i = 0; i < _d_output.size(); i++) { //CHECK-NEXT: _EERepl_output0[i] = output[i]; //CHECK-NEXT: } -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; //CHECK-NEXT: double _EERepl_output1; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; +//CHECK-NEXT: double _t1; //CHECK-NEXT: double _EERepl_output2; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: double _t9; -//CHECK-NEXT: double _t10; -//CHECK-NEXT: double _t11; +//CHECK-NEXT: double _t2; //CHECK-NEXT: double _EERepl_output3; //CHECK-NEXT: double _ret_value0 = 0; -//CHECK-NEXT: _t1 = x[1]; -//CHECK-NEXT: _t0 = y[2]; -//CHECK-NEXT: _t3 = x[2]; -//CHECK-NEXT: _t2 = y[1]; -//CHECK-NEXT: output[0] = _t1 * _t0 - _t3 * _t2; +//CHECK-NEXT: _t0 = output[0]; +//CHECK-NEXT: output[0] = x[1] * y[2] - x[2] * y[1]; //CHECK-NEXT: _EERepl_output1 = output[0]; -//CHECK-NEXT: _t5 = x[2]; -//CHECK-NEXT: _t4 = y[0]; -//CHECK-NEXT: _t7 = x[0]; -//CHECK-NEXT: _t6 = y[2]; -//CHECK-NEXT: output[1] = _t5 * _t4 - _t7 * _t6; +//CHECK-NEXT: _t1 = output[1]; +//CHECK-NEXT: output[1] = x[2] * y[0] - x[0] * y[2]; //CHECK-NEXT: _EERepl_output2 = output[1]; -//CHECK-NEXT: _t9 = x[0]; -//CHECK-NEXT: _t8 = y[1]; -//CHECK-NEXT: _t11 = y[0]; -//CHECK-NEXT: _t10 = x[1]; -//CHECK-NEXT: output[2] = _t9 * _t8 - _t11 * _t10; +//CHECK-NEXT: _t2 = output[2]; +//CHECK-NEXT: output[2] = x[0] * y[1] - y[0] * x[1]; //CHECK-NEXT: _EERepl_output3 = output[2]; //CHECK-NEXT: _ret_value0 = output[0] + output[1] + output[2]; //CHECK-NEXT: goto _label0; @@ -314,14 +308,15 @@ double func5(double* x, double* y, double* output) { //CHECK-NEXT: _d_output[2] += 1; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: output[2] = _t2; //CHECK-NEXT: double _r_d2 = _d_output[2]; -//CHECK-NEXT: double _r8 = _r_d2 * _t8; +//CHECK-NEXT: double _r8 = _r_d2 * y[1]; //CHECK-NEXT: _d_x[0] += _r8; -//CHECK-NEXT: double _r9 = _t9 * _r_d2; +//CHECK-NEXT: double _r9 = x[0] * _r_d2; //CHECK-NEXT: _d_y[1] += _r9; -//CHECK-NEXT: double _r10 = -_r_d2 * _t10; +//CHECK-NEXT: double _r10 = -_r_d2 * x[1]; //CHECK-NEXT: _d_y[0] += _r10; -//CHECK-NEXT: double _r11 = _t11 * -_r_d2; +//CHECK-NEXT: double _r11 = y[0] * -_r_d2; //CHECK-NEXT: _d_x[1] += _r11; //CHECK-NEXT: _delta_output[2] += std::abs(_r_d2 * _EERepl_output3 * {{.+}}); //CHECK-NEXT: _final_error += _delta_output[2]; @@ -329,14 +324,15 @@ double func5(double* x, double* y, double* output) { //CHECK-NEXT: _d_output[2]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: output[1] = _t1; //CHECK-NEXT: double _r_d1 = _d_output[1]; -//CHECK-NEXT: double _r4 = _r_d1 * _t4; +//CHECK-NEXT: double _r4 = _r_d1 * y[0]; //CHECK-NEXT: _d_x[2] += _r4; -//CHECK-NEXT: double _r5 = _t5 * _r_d1; +//CHECK-NEXT: double _r5 = x[2] * _r_d1; //CHECK-NEXT: _d_y[0] += _r5; -//CHECK-NEXT: double _r6 = -_r_d1 * _t6; +//CHECK-NEXT: double _r6 = -_r_d1 * y[2]; //CHECK-NEXT: _d_x[0] += _r6; -//CHECK-NEXT: double _r7 = _t7 * -_r_d1; +//CHECK-NEXT: double _r7 = x[0] * -_r_d1; //CHECK-NEXT: _d_y[2] += _r7; //CHECK-NEXT: _delta_output[1] += std::abs(_r_d1 * _EERepl_output2 * {{.+}}); //CHECK-NEXT: _final_error += _delta_output[1]; @@ -344,14 +340,15 @@ double func5(double* x, double* y, double* output) { //CHECK-NEXT: _d_output[1]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: output[0] = _t0; //CHECK-NEXT: double _r_d0 = _d_output[0]; -//CHECK-NEXT: double _r0 = _r_d0 * _t0; +//CHECK-NEXT: double _r0 = _r_d0 * y[2]; //CHECK-NEXT: _d_x[1] += _r0; -//CHECK-NEXT: double _r1 = _t1 * _r_d0; +//CHECK-NEXT: double _r1 = x[1] * _r_d0; //CHECK-NEXT: _d_y[2] += _r1; -//CHECK-NEXT: double _r2 = -_r_d0 * _t2; +//CHECK-NEXT: double _r2 = -_r_d0 * y[1]; //CHECK-NEXT: _d_x[2] += _r2; -//CHECK-NEXT: double _r3 = _t3 * -_r_d0; +//CHECK-NEXT: double _r3 = x[2] * -_r_d0; //CHECK-NEXT: _d_y[1] += _r3; //CHECK-NEXT: _delta_output[0] += std::abs(_r_d0 * _EERepl_output1 * {{.+}}); //CHECK-NEXT: _final_error += _delta_output[0]; @@ -361,22 +358,22 @@ double func5(double* x, double* y, double* output) { //CHECK-NEXT: clad::array _delta_x(_d_x.size()); //CHECK-NEXT: int i = 0; //CHECK-NEXT: for (; i < _d_x.size(); i++) { -//CHECK-NEXT: double _t12 = std::abs(_d_x[i] * x[i] * {{.+}}); -//CHECK-NEXT: _delta_x[i] += _t12; -//CHECK-NEXT: _final_error += _t12; +//CHECK-NEXT: double _t3 = std::abs(_d_x[i] * x[i] * {{.+}}); +//CHECK-NEXT: _delta_x[i] += _t3; +//CHECK-NEXT: _final_error += _t3; //CHECK-NEXT: } //CHECK-NEXT: clad::array _delta_y(_d_y.size()); //CHECK-NEXT: i = 0; //CHECK-NEXT: for (; i < _d_y.size(); i++) { -//CHECK-NEXT: double _t13 = std::abs(_d_y[i] * y[i] * {{.+}}); -//CHECK-NEXT: _delta_y[i] += _t13; -//CHECK-NEXT: _final_error += _t13; +//CHECK-NEXT: double _t4 = std::abs(_d_y[i] * y[i] * {{.+}}); +//CHECK-NEXT: _delta_y[i] += _t4; +//CHECK-NEXT: _final_error += _t4; //CHECK-NEXT: } //CHECK-NEXT: i = 0; //CHECK-NEXT: for (; i < _d_output.size(); i++) { -//CHECK-NEXT: double _t14 = std::abs(_d_output[i] * _EERepl_output0[i] * {{.+}}); -//CHECK-NEXT: _delta_output[i] += _t14; -//CHECK-NEXT: _final_error += _t14; +//CHECK-NEXT: double _t5 = std::abs(_d_output[i] * _EERepl_output0[i] * {{.+}}); +//CHECK-NEXT: _delta_output[i] += _t5; +//CHECK-NEXT: _final_error += _t5; //CHECK-NEXT: } //CHECK-NEXT: _final_error += std::abs(1. * _ret_value0 * {{.+}}); //CHECK-NEXT: } diff --git a/test/ErrorEstimation/LoopsAndArraysExec.C b/test/ErrorEstimation/LoopsAndArraysExec.C index 7def734d1..addbcc48a 100644 --- a/test/ErrorEstimation/LoopsAndArraysExec.C +++ b/test/ErrorEstimation/LoopsAndArraysExec.C @@ -21,28 +21,28 @@ double runningSum(float* f, int n) { //CHECK-NEXT: double _EERepl_sum0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t3 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: double sum = 0; //CHECK-NEXT: _EERepl_sum0 = sum; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 1; i < n; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: sum += f[clad::push(_t1, i)] + f[clad::push(_t3, i - 1)]; +//CHECK-NEXT: clad::push(_t1, sum); +//CHECK-NEXT: sum += f[i] + f[i - 1]; //CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_sum; //CHECK-NEXT: _d_sum += _r_d0; -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: _d_f[_t2] += _r_d0; -//CHECK-NEXT: int _t4 = clad::pop(_t3); -//CHECK-NEXT: _d_f[_t4] += _r_d0; +//CHECK-NEXT: _d_f[i] += _r_d0; +//CHECK-NEXT: _d_f[i - 1] += _r_d0; //CHECK-NEXT: double _r0 = clad::pop(_EERepl_sum1); //CHECK-NEXT: _delta_sum += std::abs(_r_d0 * _r0 * {{.+}}); //CHECK-NEXT: _d_sum -= _r_d0; @@ -52,9 +52,9 @@ double runningSum(float* f, int n) { //CHECK-NEXT: clad::array _delta_f(_d_f.size()); //CHECK-NEXT: int i = 0; //CHECK-NEXT: for (; i < _d_f.size(); i++) { -//CHECK-NEXT: double _t5 = std::abs(_d_f[i] * f[i] * {{.+}}); -//CHECK-NEXT: _delta_f[i] += _t5; -//CHECK-NEXT: _final_error += _t5; +//CHECK-NEXT: double _t2 = std::abs(_d_f[i] * f[i] * {{.+}}); +//CHECK-NEXT: _delta_f[i] += _t2; +//CHECK-NEXT: _final_error += _t2; //CHECK-NEXT: } //CHECK-NEXT: _final_error += _delta_sum; //CHECK-NEXT: } @@ -75,11 +75,10 @@ double mulSum(float* a, float* b, int n) { //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: int _d_j = 0; -//CHECK-NEXT: clad::tape _t2 = {}; -//CHECK-NEXT: clad::tape _t3 = {}; -//CHECK-NEXT: clad::tape _t5 = {}; -//CHECK-NEXT: clad::tape _t6 = {}; +//CHECK-NEXT: int j = 0; +//CHECK-NEXT: clad::tape _t3 = {}; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: double sum = 0; //CHECK-NEXT: _EERepl_sum0 = sum; @@ -87,9 +86,10 @@ double mulSum(float* a, float* b, int n) { //CHECK-NEXT: for (int i = 0; i < n; i++) { //CHECK-NEXT: _t0++; //CHECK-NEXT: clad::push(_t1, 0UL); -//CHECK-NEXT: for (int j = 0; j < n; j++) { +//CHECK-NEXT: for (clad::push(_t2, j) , j = 0; j < n; j++) { //CHECK-NEXT: clad::back(_t1)++; -//CHECK-NEXT: sum += clad::push(_t5, a[clad::push(_t3, i)]) * clad::push(_t2, b[clad::push(_t6, j)]); +//CHECK-NEXT: clad::push(_t3, sum); +//CHECK-NEXT: sum += a[i] * b[j]; //CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: } @@ -97,21 +97,25 @@ double mulSum(float* a, float* b, int n) { //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { //CHECK-NEXT: for (; clad::back(_t1); clad::back(_t1)--) { +//CHECK-NEXT: j--; +//CHECK-NEXT: sum = clad::pop(_t3); //CHECK-NEXT: double _r_d0 = _d_sum; //CHECK-NEXT: _d_sum += _r_d0; -//CHECK-NEXT: double _r0 = _r_d0 * clad::pop(_t2); -//CHECK-NEXT: int _t4 = clad::pop(_t3); -//CHECK-NEXT: _d_a[_t4] += _r0; -//CHECK-NEXT: double _r1 = clad::pop(_t5) * _r_d0; -//CHECK-NEXT: int _t7 = clad::pop(_t6); -//CHECK-NEXT: _d_b[_t7] += _r1; +//CHECK-NEXT: double _r0 = _r_d0 * b[j]; +//CHECK-NEXT: _d_a[i] += _r0; +//CHECK-NEXT: double _r1 = a[i] * _r_d0; +//CHECK-NEXT: _d_b[j] += _r1; //CHECK-NEXT: double _r2 = clad::pop(_EERepl_sum1); //CHECK-NEXT: _delta_sum += std::abs(_r_d0 * _r2 * {{.+}}); //CHECK-NEXT: _d_sum -= _r_d0; //CHECK-NEXT: } -//CHECK-NEXT: _d_j = 0; +//CHECK-NEXT: { +//CHECK-NEXT: _d_j = 0; +//CHECK-NEXT: j = clad::pop(_t2); +//CHECK-NEXT: } //CHECK-NEXT: clad::pop(_t1); //CHECK-NEXT: } //CHECK-NEXT: } @@ -119,16 +123,16 @@ double mulSum(float* a, float* b, int n) { //CHECK-NEXT: clad::array _delta_a(_d_a.size()); //CHECK-NEXT: int i = 0; //CHECK-NEXT: for (; i < _d_a.size(); i++) { -//CHECK-NEXT: double _t8 = std::abs(_d_a[i] * a[i] * {{.+}}); -//CHECK-NEXT: _delta_a[i] += _t8; -//CHECK-NEXT: _final_error += _t8; +//CHECK-NEXT: double _t4 = std::abs(_d_a[i] * a[i] * {{.+}}); +//CHECK-NEXT: _delta_a[i] += _t4; +//CHECK-NEXT: _final_error += _t4; //CHECK-NEXT: } //CHECK-NEXT: clad::array _delta_b(_d_b.size()); //CHECK-NEXT: i = 0; //CHECK-NEXT: for (; i < _d_b.size(); i++) { -//CHECK-NEXT: double _t9 = std::abs(_d_b[i] * b[i] * {{.+}}); -//CHECK-NEXT: _delta_b[i] += _t9; -//CHECK-NEXT: _final_error += _t9; +//CHECK-NEXT: double _t5 = std::abs(_d_b[i] * b[i] * {{.+}}); +//CHECK-NEXT: _delta_b[i] += _t5; +//CHECK-NEXT: _final_error += _t5; //CHECK-NEXT: } //CHECK-NEXT: _final_error += _delta_sum; //CHECK-NEXT: } @@ -147,33 +151,32 @@ double divSum(float* a, float* b, int n) { //CHECK-NEXT: double _EERepl_sum0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t2 = {}; -//CHECK-NEXT: clad::tape _t4 = {}; -//CHECK-NEXT: clad::tape _t5 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: clad::tape _EERepl_sum1 = {}; //CHECK-NEXT: double sum = 0; //CHECK-NEXT: _EERepl_sum0 = sum; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < n; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: sum += clad::push(_t4, a[clad::push(_t2, i)]) / clad::push(_t1, b[clad::push(_t5, i)]); +//CHECK-NEXT: clad::push(_t1, sum); +//CHECK-NEXT: sum += a[i] / clad::push(_t2, b[i]); //CHECK-NEXT: clad::push(_EERepl_sum1, sum); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_sum += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: sum = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_sum; //CHECK-NEXT: _d_sum += _r_d0; -//CHECK-NEXT: float _r0 = clad::pop(_t1); +//CHECK-NEXT: float _r0 = clad::pop(_t2); //CHECK-NEXT: double _r1 = _r_d0 / _r0; -//CHECK-NEXT: int _t3 = clad::pop(_t2); -//CHECK-NEXT: _d_a[_t3] += _r1; -//CHECK-NEXT: double _r2 = _r_d0 * -clad::pop(_t4) / (_r0 * _r0); -//CHECK-NEXT: int _t6 = clad::pop(_t5); -//CHECK-NEXT: _d_b[_t6] += _r2; +//CHECK-NEXT: _d_a[i] += _r1; +//CHECK-NEXT: double _r2 = _r_d0 * -a[i] / (_r0 * _r0); +//CHECK-NEXT: _d_b[i] += _r2; //CHECK-NEXT: double _r3 = clad::pop(_EERepl_sum1); //CHECK-NEXT: _delta_sum += std::abs(_r_d0 * _r3 * {{.+}}); //CHECK-NEXT: _d_sum -= _r_d0; @@ -183,16 +186,16 @@ double divSum(float* a, float* b, int n) { //CHECK-NEXT: clad::array _delta_a(_d_a.size()); //CHECK-NEXT: int i = 0; //CHECK-NEXT: for (; i < _d_a.size(); i++) { -//CHECK-NEXT: double _t7 = std::abs(_d_a[i] * a[i] * {{.+}}); -//CHECK-NEXT: _delta_a[i] += _t7; -//CHECK-NEXT: _final_error += _t7; +//CHECK-NEXT: double _t3 = std::abs(_d_a[i] * a[i] * {{.+}}); +//CHECK-NEXT: _delta_a[i] += _t3; +//CHECK-NEXT: _final_error += _t3; //CHECK-NEXT: } //CHECK-NEXT: clad::array _delta_b(_d_b.size()); //CHECK-NEXT: i = 0; //CHECK-NEXT: for (; i < _d_b.size(); i++) { -//CHECK-NEXT: double _t8 = std::abs(_d_b[i] * b[i] * {{.+}}); -//CHECK-NEXT: _delta_b[i] += _t8; -//CHECK-NEXT: _final_error += _t8; +//CHECK-NEXT: double _t4 = std::abs(_d_b[i] * b[i] * {{.+}}); +//CHECK-NEXT: _delta_b[i] += _t4; +//CHECK-NEXT: _final_error += _t4; //CHECK-NEXT: } //CHECK-NEXT: _final_error += _delta_sum; //CHECK-NEXT: } diff --git a/test/FirstDerivative/BuiltinDerivatives.C b/test/FirstDerivative/BuiltinDerivatives.C index 34d7b15ef..33b7acca7 100644 --- a/test/FirstDerivative/BuiltinDerivatives.C +++ b/test/FirstDerivative/BuiltinDerivatives.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -Xclang -verify -oBuiltinDerivatives.out 2>&1 | FileCheck %s // RUN: ./BuiltinDerivatives.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -Xclang -verify -oBuiltinDerivatives.out +// RUN: ./BuiltinDerivatives.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -100,14 +102,12 @@ float f7(float x) { void f7_grad(float x, clad::array_ref _d_x); // CHECK: void f7_grad(float x, clad::array_ref _d_x) { -// CHECK-NEXT: float _t0; -// CHECK-NEXT: _t0 = x; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: float _grad0 = 0.F; // CHECK-NEXT: double _grad1 = 0.; -// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(_t0, 2., 1, &_grad0, &_grad1); +// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(x, 2., 1, &_grad0, &_grad1); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: double _r1 = _grad1; @@ -127,14 +127,12 @@ double f8(float x) { void f8_grad(float x, clad::array_ref _d_x); // CHECK: void f8_grad(float x, clad::array_ref _d_x) { -// CHECK-NEXT: float _t0; -// CHECK-NEXT: _t0 = x; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: float _grad0 = 0.F; // CHECK-NEXT: int _grad1 = 0; -// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(_t0, 2, 1, &_grad0, &_grad1); +// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(x, 2, 1, &_grad0, &_grad1); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: int _r1 = _grad1; @@ -155,16 +153,12 @@ float f9(float x, float y) { void f9_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y); // CHECK: void f9_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y) { -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = y; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: float _grad0 = 0.F; // CHECK-NEXT: float _grad1 = 0.F; -// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(_t0, _t1, 1, &_grad0, &_grad1); +// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(x, y, 1, &_grad0, &_grad1); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: float _r1 = _grad1; @@ -186,16 +180,12 @@ double f10(float x, int y) { void f10_grad(float x, int y, clad::array_ref _d_x, clad::array_ref _d_y); // CHECK: void f10_grad(float x, int y, clad::array_ref _d_x, clad::array_ref _d_y) { -// CHECK-NEXT: float _t0; -// CHECK-NEXT: int _t1; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = y; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: float _grad0 = 0.F; // CHECK-NEXT: int _grad1 = 0; -// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(_t0, _t1, 1, &_grad0, &_grad1); +// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(x, y, 1, &_grad0, &_grad1); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: int _r1 = _grad1; @@ -208,33 +198,27 @@ double f11(double x, double y) { } // CHECK: void f11_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: typename {{.*}} _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: _t0 = (1. - x); -// CHECK-NEXT: _t2 = x; -// CHECK-NEXT: _t3 = y - std::pow(_t2, 2); -// CHECK-NEXT: _t1 = std::pow(_t3, 2); +// CHECK-NEXT: typename {{.*}} _t0; +// CHECK-NEXT: _t0 = std::pow(y - std::pow(x, 2), 2); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: double _grad0 = 0.; // CHECK-NEXT: int _grad1 = 0; -// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(_t0, 2, 1, &_grad0, &_grad1); +// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback((1. - x), 2, 1, &_grad0, &_grad1); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: * _d_x += -_r0; // CHECK-NEXT: int _r1 = _grad1; -// CHECK-NEXT: double _r2 = 1 * _t1; +// CHECK-NEXT: double _r2 = 1 * _t0; // CHECK-NEXT: double _r3 = 100. * 1; // CHECK-NEXT: double _grad4 = 0.; // CHECK-NEXT: int _grad5 = 0; -// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(_t3, 2, _r3, &_grad4, &_grad5); +// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(y - std::pow(x, 2), 2, _r3, &_grad4, &_grad5); // CHECK-NEXT: double _r4 = _grad4; // CHECK-NEXT: * _d_y += _r4; // CHECK-NEXT: double _grad2 = 0.; // CHECK-NEXT: int _grad3 = 0; -// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(_t2, 2, -_r4, &_grad2, &_grad3); +// CHECK-NEXT: {{(clad::)?}}custom_derivatives{{(::std)?}}::pow_pullback(x, 2, -_r4, &_grad2, &_grad3); // CHECK-NEXT: double _r5 = _grad2; // CHECK-NEXT: * _d_x += _r5; // CHECK-NEXT: int _r6 = _grad3; diff --git a/test/FirstDerivative/FunctionCalls.C b/test/FirstDerivative/FunctionCalls.C index 639eb69bf..be8006bd7 100644 --- a/test/FirstDerivative/FunctionCalls.C +++ b/test/FirstDerivative/FunctionCalls.C @@ -136,7 +136,7 @@ double test_7(double i, double j) { // CHECK-NEXT: double res = 0; // CHECK-NEXT: { // CHECK-NEXT: int _d_i0 = 0; -// CHECK-NEXT: for (int i0 = 0; i < 5; increment_pushforward(i0, _d_i0)) { +// CHECK-NEXT: for (int i0 = 0; i0 < 5; increment_pushforward(i0, _d_i0)) { // CHECK-NEXT: _d_res += _d_i0 * j + i0 * _d_j; // CHECK-NEXT: res += i0 * j; // CHECK-NEXT: } diff --git a/test/FirstDerivative/UnsupportedOpsWarn.C b/test/FirstDerivative/UnsupportedOpsWarn.C index fba84186c..2a618c54d 100644 --- a/test/FirstDerivative/UnsupportedOpsWarn.C +++ b/test/FirstDerivative/UnsupportedOpsWarn.C @@ -1,4 +1,5 @@ // RUN: %cladclang %s -I%S/../../include -fsyntax-only -Xclang -verify 2>&1 | FileCheck %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -fsyntax-only -Xclang -verify #include "clad/Differentiator/Differentiator.h" diff --git a/test/Gradient/Assignments.C b/test/Gradient/Assignments.C index bf0514afd..d524f6ca8 100644 --- a/test/Gradient/Assignments.C +++ b/test/Gradient/Assignments.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oReverseAssignments.out 2>&1 | FileCheck %s // RUN: ./ReverseAssignments.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oReverseAssignments.out +// RUN: ./ReverseAssignments.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" @@ -12,11 +14,14 @@ double f1(double x, double y) { } //CHECK: void f1_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { +//CHECK-NEXT: double _t0; +//CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_y += 1; //CHECK-NEXT: { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: double _r_d0 = * _d_x; //CHECK-NEXT: * _d_y += _r_d0; //CHECK-NEXT: * _d_x -= _r_d0; @@ -33,13 +38,17 @@ double f2(double x, double y) { //CHECK: void f2_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { //CHECK-NEXT: bool _cond0; +//CHECK-NEXT: double _t0; //CHECK-NEXT: _cond0 = x < y; -//CHECK-NEXT: if (_cond0) +//CHECK-NEXT: if (_cond0) { +//CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = y; +//CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_x += 1; //CHECK-NEXT: if (_cond0) { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: double _r_d0 = * _d_x; //CHECK-NEXT: * _d_y += _r_d0; //CHECK-NEXT: * _d_x -= _r_d0; @@ -61,42 +70,46 @@ double f3(double x, double y) { //CHECK-NEXT: double _t1; //CHECK-NEXT: double _t2; //CHECK-NEXT: double _t3; +//CHECK-NEXT: _t0 = x; //CHECK-NEXT: x = x; //CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: x = _t1 * _t0; +//CHECK-NEXT: x = x * x; +//CHECK-NEXT: _t2 = y; +//CHECK-NEXT: y = x * x; //CHECK-NEXT: _t3 = x; -//CHECK-NEXT: _t2 = x; -//CHECK-NEXT: y = _t3 * _t2; //CHECK-NEXT: x = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_y += 1; //CHECK-NEXT: { +//CHECK-NEXT: x = _t3; //CHECK-NEXT: double _r_d3 = * _d_x; //CHECK-NEXT: * _d_y += _r_d3; //CHECK-NEXT: * _d_x -= _r_d3; //CHECK-NEXT: * _d_x; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: y = _t2; //CHECK-NEXT: double _r_d2 = * _d_y; -//CHECK-NEXT: double _r2 = _r_d2 * _t2; +//CHECK-NEXT: double _r2 = _r_d2 * x; //CHECK-NEXT: * _d_x += _r2; -//CHECK-NEXT: double _r3 = _t3 * _r_d2; +//CHECK-NEXT: double _r3 = x * _r_d2; //CHECK-NEXT: * _d_x += _r3; //CHECK-NEXT: * _d_y -= _r_d2; //CHECK-NEXT: * _d_y; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: x = _t1; //CHECK-NEXT: double _r_d1 = * _d_x; -//CHECK-NEXT: double _r0 = _r_d1 * _t0; +//CHECK-NEXT: double _r0 = _r_d1 * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _r_d1; +//CHECK-NEXT: double _r1 = x * _r_d1; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: * _d_x -= _r_d1; //CHECK-NEXT: * _d_x; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: x = _t0; //CHECK-NEXT: double _r_d0 = * _d_x; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_x -= _r_d0; @@ -112,17 +125,23 @@ double f4(double x, double y) { } //CHECK: void f4_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { +//CHECK-NEXT: double _t0; +//CHECK-NEXT: double _t1; +//CHECK-NEXT: _t0 = y; //CHECK-NEXT: y = x; +//CHECK-NEXT: _t1 = x; //CHECK-NEXT: x = 0; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_y += 1; //CHECK-NEXT: { +//CHECK-NEXT: x = _t1; //CHECK-NEXT: double _r_d1 = * _d_x; //CHECK-NEXT: * _d_x -= _r_d1; //CHECK-NEXT: * _d_x; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: y = _t0; //CHECK-NEXT: double _r_d0 = * _d_y; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_y -= _r_d0; @@ -145,23 +164,23 @@ double f5(double x, double y) { } //CHECK: void f5_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; //CHECK-NEXT: double _d_t = 0; //CHECK-NEXT: bool _cond0; +//CHECK-NEXT: double _t0; //CHECK-NEXT: bool _cond1; //CHECK-NEXT: double _d_z = 0; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: double t = _t1 * _t0; +//CHECK-NEXT: double _t1; +//CHECK-NEXT: double t = x * x; //CHECK-NEXT: _cond0 = x < 0; //CHECK-NEXT: if (_cond0) { +//CHECK-NEXT: _t0 = t; //CHECK-NEXT: t = -t; //CHECK-NEXT: goto _label0; //CHECK-NEXT: } //CHECK-NEXT: _cond1 = y < 0; //CHECK-NEXT: if (_cond1) { //CHECK-NEXT: double z = t; +//CHECK-NEXT: _t1 = t; //CHECK-NEXT: t = -t; //CHECK-NEXT: } //CHECK-NEXT: goto _label1; @@ -169,6 +188,7 @@ double f5(double x, double y) { //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: if (_cond1) { //CHECK-NEXT: { +//CHECK-NEXT: t = _t1; //CHECK-NEXT: double _r_d1 = _d_t; //CHECK-NEXT: _d_t += -_r_d1; //CHECK-NEXT: _d_t -= _r_d1; @@ -179,15 +199,16 @@ double f5(double x, double y) { //CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: { +//CHECK-NEXT: t = _t0; //CHECK-NEXT: double _r_d0 = _d_t; //CHECK-NEXT: _d_t += -_r_d0; //CHECK-NEXT: _d_t -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_t * _t0; +//CHECK-NEXT: double _r0 = _d_t * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d_t; +//CHECK-NEXT: double _r1 = x * _d_t; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: } //CHECK-NEXT: } @@ -207,23 +228,23 @@ double f6(double x, double y) { } //CHECK: void f6_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; //CHECK-NEXT: double _d_t = 0; //CHECK-NEXT: bool _cond0; +//CHECK-NEXT: double _t0; //CHECK-NEXT: bool _cond1; //CHECK-NEXT: double _d_z = 0; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: double t = _t1 * _t0; +//CHECK-NEXT: double _t1; +//CHECK-NEXT: double t = x * x; //CHECK-NEXT: _cond0 = x < 0; //CHECK-NEXT: if (_cond0) { +//CHECK-NEXT: _t0 = t; //CHECK-NEXT: t = -t; //CHECK-NEXT: goto _label0; //CHECK-NEXT: } //CHECK-NEXT: _cond1 = y < 0; //CHECK-NEXT: if (_cond1) { //CHECK-NEXT: double z = t; +//CHECK-NEXT: _t1 = t; //CHECK-NEXT: t = -t; //CHECK-NEXT: } //CHECK-NEXT: goto _label1; @@ -231,6 +252,7 @@ double f6(double x, double y) { //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: if (_cond1) { //CHECK-NEXT: { +//CHECK-NEXT: t = _t1; //CHECK-NEXT: double _r_d1 = _d_t; //CHECK-NEXT: _d_t += -_r_d1; //CHECK-NEXT: _d_t -= _r_d1; @@ -241,15 +263,16 @@ double f6(double x, double y) { //CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: { +//CHECK-NEXT: t = _t0; //CHECK-NEXT: double _r_d0 = _d_t; //CHECK-NEXT: _d_t += -_r_d0; //CHECK-NEXT: _d_t -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_t * _t0; +//CHECK-NEXT: double _r0 = _d_t * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d_t; +//CHECK-NEXT: double _r1 = x * _d_t; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: } //CHECK-NEXT: } @@ -271,41 +294,48 @@ double f7(double x, double y) { } //CHECK: void f7_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { +//CHECK-NEXT: clad::array _d_t(3UL); //CHECK-NEXT: double _t0; //CHECK-NEXT: double _t1; -//CHECK-NEXT: clad::array _d_t(3UL); //CHECK-NEXT: double _t2; //CHECK-NEXT: double _t3; //CHECK-NEXT: double _t4; //CHECK-NEXT: double _t5; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: double t[3] = {1, x, _t1 * _t0}; +//CHECK-NEXT: double _t6; +//CHECK-NEXT: double _t7; +//CHECK-NEXT: double t[3] = {1, x, x * x}; //CHECK-NEXT: t[0]++; //CHECK-NEXT: t[0]--; //CHECK-NEXT: ++t[0]; //CHECK-NEXT: --t[0]; +//CHECK-NEXT: _t0 = t[0]; //CHECK-NEXT: t[0] = x; +//CHECK-NEXT: _t1 = x; //CHECK-NEXT: x = y; +//CHECK-NEXT: _t2 = t[0]; //CHECK-NEXT: t[0] += t[1]; //CHECK-NEXT: _t3 = t[0]; -//CHECK-NEXT: _t2 = t[1]; -//CHECK-NEXT: t[0] *= _t2; -//CHECK-NEXT: _t5 = t[0]; -//CHECK-NEXT: _t4 = t[1]; -//CHECK-NEXT: t[0] /= _t4; +//CHECK-NEXT: t[0] *= t[1]; +//CHECK-NEXT: _t4 = t[0]; +//CHECK-NEXT: _t5 = t[1]; +//CHECK-NEXT: t[0] /= _t5; +//CHECK-NEXT: _t6 = t[0]; //CHECK-NEXT: t[0] -= t[1]; +//CHECK-NEXT: _t7 = x; //CHECK-NEXT: x = ++t[0]; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_t[0] += 1; //CHECK-NEXT: { +//CHECK-NEXT: x = _t7; //CHECK-NEXT: double _r_d6 = * _d_x; //CHECK-NEXT: _d_t[0] += _r_d6; +//CHECK-NEXT: --t[0]; //CHECK-NEXT: * _d_x -= _r_d6; //CHECK-NEXT: * _d_x; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: t[0] = _t6; //CHECK-NEXT: double _r_d5 = _d_t[0]; //CHECK-NEXT: _d_t[0] += _r_d5; //CHECK-NEXT: _d_t[1] += -_r_d5; @@ -313,22 +343,25 @@ double f7(double x, double y) { //CHECK-NEXT: _d_t[0]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: t[0] = _t4; //CHECK-NEXT: double _r_d4 = _d_t[0]; -//CHECK-NEXT: _d_t[0] += _r_d4 / _t4; -//CHECK-NEXT: double _r3 = _r_d4 * -_t5 / (_t4 * _t4); +//CHECK-NEXT: _d_t[0] += _r_d4 / _t5; +//CHECK-NEXT: double _r3 = _r_d4 * -t[0] / (_t5 * _t5); //CHECK-NEXT: _d_t[1] += _r3; //CHECK-NEXT: _d_t[0] -= _r_d4; //CHECK-NEXT: _d_t[0]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: t[0] = _t3; //CHECK-NEXT: double _r_d3 = _d_t[0]; -//CHECK-NEXT: _d_t[0] += _r_d3 * _t2; -//CHECK-NEXT: double _r2 = _t3 * _r_d3; +//CHECK-NEXT: _d_t[0] += _r_d3 * t[1]; +//CHECK-NEXT: double _r2 = t[0] * _r_d3; //CHECK-NEXT: _d_t[1] += _r2; //CHECK-NEXT: _d_t[0] -= _r_d3; //CHECK-NEXT: _d_t[0]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: t[0] = _t2; //CHECK-NEXT: double _r_d2 = _d_t[0]; //CHECK-NEXT: _d_t[0] += _r_d2; //CHECK-NEXT: _d_t[1] += _r_d2; @@ -336,24 +369,34 @@ double f7(double x, double y) { //CHECK-NEXT: _d_t[0]; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: x = _t1; //CHECK-NEXT: double _r_d1 = * _d_x; //CHECK-NEXT: * _d_y += _r_d1; //CHECK-NEXT: * _d_x -= _r_d1; //CHECK-NEXT: * _d_x; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: t[0] = _t0; //CHECK-NEXT: double _r_d0 = _d_t[0]; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: _d_t[0] -= _r_d0; //CHECK-NEXT: _d_t[0]; //CHECK-NEXT: } -//CHECK-NEXT: _d_t[0]; -//CHECK-NEXT: _d_t[0]; +//CHECK-NEXT: ++t[0]; +//CHECK-NEXT: --t[0]; +//CHECK-NEXT: { +//CHECK-NEXT: t[0]++; +//CHECK-NEXT: _d_t[0]; +//CHECK-NEXT: } +//CHECK-NEXT: { +//CHECK-NEXT: t[0]--; +//CHECK-NEXT: _d_t[0]; +//CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: * _d_x += _d_t[1]; -//CHECK-NEXT: double _r0 = _d_t[2] * _t0; +//CHECK-NEXT: double _r0 = _d_t[2] * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d_t[2]; +//CHECK-NEXT: double _r1 = x * _d_t[2]; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: } //CHECK-NEXT: } @@ -364,26 +407,34 @@ double f8(double x, double y) { return t[3]; // == y * y } -//CHECK: void f8_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { +//CHECK: void f8_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { //CHECK-NEXT: clad::array _d_t(4UL); //CHECK-NEXT: double _t0; //CHECK-NEXT: double _t1; +//CHECK-NEXT: double _t2; +//CHECK-NEXT: double _t3; //CHECK-NEXT: double t[4] = {1, x, y, 1}; +//CHECK-NEXT: _t0 = t[3]; //CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t0 = (t[0] = t[1] = t[2]); -//CHECK-NEXT: t[3] = (y *= _t0); +//CHECK-NEXT: _t2 = t[0]; +//CHECK-NEXT: _t3 = t[1]; +//CHECK-NEXT: t[3] = (y *= (t[0] = t[1] = t[2])); //CHECK-NEXT: goto _label0; -//CHECK-NEXT: _label0: +//CHECK-NEXT: _label0: //CHECK-NEXT: _d_t[3] += 1; //CHECK-NEXT: { +//CHECK-NEXT: t[3] = _t0; //CHECK-NEXT: double _r_d0 = _d_t[3]; //CHECK-NEXT: * _d_y += _r_d0; +//CHECK-NEXT: y = _t1; //CHECK-NEXT: double _r_d1 = * _d_y; -//CHECK-NEXT: * _d_y += _r_d1 * _t0; -//CHECK-NEXT: double _r0 = _t1 * _r_d1; +//CHECK-NEXT: * _d_y += _r_d1 * t[2]; +//CHECK-NEXT: double _r0 = y * _r_d1; //CHECK-NEXT: _d_t[0] += _r0; +//CHECK-NEXT: t[0] = _t2; //CHECK-NEXT: double _r_d2 = _d_t[0]; //CHECK-NEXT: _d_t[1] += _r_d2; +//CHECK-NEXT: t[1] = _t3; //CHECK-NEXT: double _r_d3 = _d_t[1]; //CHECK-NEXT: _d_t[2] += _r_d3; //CHECK-NEXT: _d_t[1] -= _r_d3; @@ -396,7 +447,7 @@ double f8(double x, double y) { //CHECK-NEXT: * _d_x += _d_t[1]; //CHECK-NEXT: * _d_y += _d_t[2]; //CHECK-NEXT: } -//CHECK-NEXT: } +//CHECK-NEXT: } double f9(double x, double y) { double t = x; @@ -407,28 +458,26 @@ double f9(double x, double y) { //CHECK: void f9_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { //CHECK-NEXT: double _d_t = 0; //CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; //CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; //CHECK-NEXT: double t = x; -//CHECK-NEXT: _t1 = t; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: double _ref0 = (t *= _t0); -//CHECK-NEXT: _t3 = _ref0; -//CHECK-NEXT: _t2 = y; -//CHECK-NEXT: _ref0 *= _t2; +//CHECK-NEXT: _t0 = t; +//CHECK-NEXT: double &_t1 = (t *= x); +//CHECK-NEXT: _t2 = t; +//CHECK-NEXT: _t1 *= y; //CHECK-NEXT: goto _label0; -//CHECK-NEXT: _label0: +//CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: { +//CHECK-NEXT: t = _t2; //CHECK-NEXT: double _r_d1 = _d_t; -//CHECK-NEXT: _d_t += _r_d1 * _t2; -//CHECK-NEXT: double _r1 = _t3 * _r_d1; +//CHECK-NEXT: _d_t += _r_d1 * y; +//CHECK-NEXT: double _r1 = _t1 * _r_d1; //CHECK-NEXT: * _d_y += _r1; //CHECK-NEXT: _d_t -= _r_d1; +//CHECK-NEXT: t = _t0; //CHECK-NEXT: double _r_d0 = _d_t; -//CHECK-NEXT: _d_t += _r_d0 * _t0; -//CHECK-NEXT: double _r0 = _t1 * _r_d0; +//CHECK-NEXT: _d_t += _r_d0 * x; +//CHECK-NEXT: double _r0 = t * _r_d0; //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: _d_t -= _r_d0; //CHECK-NEXT: } @@ -443,14 +492,20 @@ double f10(double x, double y) { //CHECK: void f10_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { //CHECK-NEXT: double _d_t = 0; +//CHECK-NEXT: double _t0; +//CHECK-NEXT: double _t1; //CHECK-NEXT: double t = x; +//CHECK-NEXT: _t0 = t; +//CHECK-NEXT: _t1 = x; //CHECK-NEXT: t = x = y; //CHECK-NEXT: goto _label0; -//CHECK-NEXT: _label0: +//CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: { +//CHECK-NEXT: t = _t0; //CHECK-NEXT: double _r_d0 = _d_t; //CHECK-NEXT: * _d_x += _r_d0; +//CHECK-NEXT: x = _t1; //CHECK-NEXT: double _r_d1 = * _d_x; //CHECK-NEXT: * _d_y += _r_d1; //CHECK-NEXT: * _d_x -= _r_d1; @@ -467,15 +522,22 @@ double f11(double x, double y) { //CHECK: void f11_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { //CHECK-NEXT: double _d_t = 0; +//CHECK-NEXT: double _t0; +//CHECK-NEXT: double _t2; //CHECK-NEXT: double t = x; -//CHECK-NEXT: (t = x) = y; +//CHECK-NEXT: _t0 = t; +//CHECK-NEXT: double &_t1 = (t = x); +//CHECK-NEXT: _t2 = t; +//CHECK-NEXT: _t1 = y; //CHECK-NEXT: goto _label0; -//CHECK-NEXT: _label0: +//CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: { +//CHECK-NEXT: t = _t2; //CHECK-NEXT: double _r_d1 = _d_t; //CHECK-NEXT: * _d_y += _r_d1; //CHECK-NEXT: _d_t -= _r_d1; +//CHECK-NEXT: t = _t0; //CHECK-NEXT: double _r_d0 = _d_t; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: _d_t -= _r_d0; @@ -494,26 +556,36 @@ double f12(double x, double y) { //CHECK-NEXT: bool _cond0; //CHECK-NEXT: double _t0; //CHECK-NEXT: double _t1; +//CHECK-NEXT: double _t3; +//CHECK-NEXT: double _t4; //CHECK-NEXT: double t; //CHECK-NEXT: _cond0 = x > y; -//CHECK-NEXT: double _ref0 = (_cond0 ? (t = x) : (t = y)); -//CHECK-NEXT: _t1 = _ref0; -//CHECK-NEXT: _t0 = y; -//CHECK-NEXT: _ref0 *= _t0; +//CHECK-NEXT: if (_cond0) +//CHECK-NEXT: _t0 = t; +//CHECK-NEXT: else +//CHECK-NEXT: _t1 = t; +//CHECK-NEXT: double &_t2 = (_cond0 ? (t = x) : (t = y)); +//CHECK-NEXT: _t3 = t; +//CHECK-NEXT: _t4 = t; +//CHECK-NEXT: _t2 *= y; //CHECK-NEXT: goto _label0; -//CHECK-NEXT: _label0: +//CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: { +//CHECK-NEXT: t = _t3; +//CHECK-NEXT: t = _t4; //CHECK-NEXT: double _r_d2 = (_cond0 ? _d_t : _d_t); -//CHECK-NEXT: (_cond0 ? _d_t : _d_t) += _r_d2 * _t0; -//CHECK-NEXT: double _r0 = _t1 * _r_d2; +//CHECK-NEXT: (_cond0 ? _d_t : _d_t) += _r_d2 * y; +//CHECK-NEXT: double _r0 = _t2 * _r_d2; //CHECK-NEXT: * _d_y += _r0; //CHECK-NEXT: (_cond0 ? _d_t : _d_t) -= _r_d2; //CHECK-NEXT: if (_cond0) { +//CHECK-NEXT: t = _t0; //CHECK-NEXT: double _r_d0 = _d_t; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: _d_t -= _r_d0; //CHECK-NEXT: } else { +//CHECK-NEXT: t = _t1; //CHECK-NEXT: double _r_d1 = _d_t; //CHECK-NEXT: * _d_y += _r_d1; //CHECK-NEXT: _d_t -= _r_d1; @@ -530,26 +602,23 @@ double f13(double x, double y) { //CHECK-NEXT: double _t0; //CHECK-NEXT: double _t1; //CHECK-NEXT: double _d_t = 0; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: _t1 = x; +//CHECK-NEXT: _t1 = y; //CHECK-NEXT: _t0 = (y = x); -//CHECK-NEXT: double t = _t1 * _t0; -//CHECK-NEXT: _t3 = t; -//CHECK-NEXT: _t2 = y; +//CHECK-NEXT: double t = x * _t0; //CHECK-NEXT: goto _label0; -//CHECK-NEXT: _label0: +//CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r2 = 1 * _t2; +//CHECK-NEXT: double _r2 = 1 * y; //CHECK-NEXT: _d_t += _r2; -//CHECK-NEXT: double _r3 = _t3 * 1; +//CHECK-NEXT: double _r3 = t * 1; //CHECK-NEXT: * _d_y += _r3; //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: double _r0 = _d_t * _t0; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d_t; +//CHECK-NEXT: double _r1 = x * _d_t; //CHECK-NEXT: * _d_y += _r1; +//CHECK-NEXT: y = _t1; //CHECK-NEXT: double _r_d0 = * _d_y; //CHECK-NEXT: * _d_x += _r_d0; //CHECK-NEXT: * _d_y -= _r_d0; @@ -571,31 +640,34 @@ double f14(double i, double j) { // CHECK-NEXT: double _t2; // CHECK-NEXT: _d_a = &* _d_i; // CHECK-NEXT: double &a = i; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: a = 2 * _t0; +// CHECK-NEXT: _t0 = a; +// CHECK-NEXT: a = 2 * i; +// CHECK-NEXT: _t1 = a; // CHECK-NEXT: a += i; // CHECK-NEXT: _t2 = a; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: a *= _t1; +// CHECK-NEXT: a *= i; // CHECK-NEXT: goto _label0; -// CHECK-NEXT: _label0: +// CHECK-NEXT: _label0: // CHECK-NEXT: * _d_i += 1; // CHECK-NEXT: { +// CHECK-NEXT: a = _t2; // CHECK-NEXT: double _r_d2 = *_d_a; -// CHECK-NEXT: *_d_a += _r_d2 * _t1; -// CHECK-NEXT: double _r2 = _t2 * _r_d2; +// CHECK-NEXT: *_d_a += _r_d2 * i; +// CHECK-NEXT: double _r2 = a * _r_d2; // CHECK-NEXT: * _d_i += _r2; // CHECK-NEXT: *_d_a -= _r_d2; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: a = _t1; // CHECK-NEXT: double _r_d1 = *_d_a; // CHECK-NEXT: *_d_a += _r_d1; // CHECK-NEXT: * _d_i += _r_d1; // CHECK-NEXT: *_d_a -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: a = _t0; // CHECK-NEXT: double _r_d0 = *_d_a; -// CHECK-NEXT: double _r0 = _r_d0 * _t0; +// CHECK-NEXT: double _r0 = _r_d0 * i; // CHECK-NEXT: double _r1 = 2 * _r_d0; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: *_d_a -= _r_d0; @@ -615,39 +687,29 @@ double f15(double i, double j) { } // CHECK: void f15_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; // CHECK-NEXT: double _d_b = 0; // CHECK-NEXT: double *_d_a = 0; // CHECK-NEXT: double *_d_c = 0; // CHECK-NEXT: double *_d_d = 0; +// CHECK-NEXT: double _t0; +// CHECK-NEXT: double _t1; // CHECK-NEXT: double _t2; // CHECK-NEXT: double _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: double _t5; -// CHECK-NEXT: double _t6; -// CHECK-NEXT: double _t7; -// CHECK-NEXT: double _t8; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t0 = j; -// CHECK-NEXT: double b = _t1 * _t0; +// CHECK-NEXT: double b = i * j; // CHECK-NEXT: _d_a = &_d_b; // CHECK-NEXT: double &a = b; // CHECK-NEXT: _d_c = &* _d_i; // CHECK-NEXT: double &c = i; // CHECK-NEXT: _d_d = &* _d_j; // CHECK-NEXT: double &d = j; -// CHECK-NEXT: _t3 = a; -// CHECK-NEXT: _t2 = i; -// CHECK-NEXT: a *= _t2; -// CHECK-NEXT: _t4 = i; -// CHECK-NEXT: b += 2 * _t4; -// CHECK-NEXT: _t5 = i; -// CHECK-NEXT: c += 3 * _t5; -// CHECK-NEXT: _t7 = d; -// CHECK-NEXT: _t8 = j; -// CHECK-NEXT: _t6 = 3 * _t8; -// CHECK-NEXT: d *= _t6; +// CHECK-NEXT: _t0 = a; +// CHECK-NEXT: a *= i; +// CHECK-NEXT: _t1 = b; +// CHECK-NEXT: b += 2 * i; +// CHECK-NEXT: _t2 = c; +// CHECK-NEXT: c += 3 * i; +// CHECK-NEXT: _t3 = d; +// CHECK-NEXT: d *= 3 * j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { @@ -656,41 +718,45 @@ double f15(double i, double j) { // CHECK-NEXT: *_d_d += 1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: d = _t3; // CHECK-NEXT: double _r_d3 = *_d_d; -// CHECK-NEXT: *_d_d += _r_d3 * _t6; -// CHECK-NEXT: double _r7 = _t7 * _r_d3; -// CHECK-NEXT: double _r8 = _r7 * _t8; +// CHECK-NEXT: *_d_d += _r_d3 * 3 * j; +// CHECK-NEXT: double _r7 = d * _r_d3; +// CHECK-NEXT: double _r8 = _r7 * j; // CHECK-NEXT: double _r9 = 3 * _r7; // CHECK-NEXT: * _d_j += _r9; // CHECK-NEXT: *_d_d -= _r_d3; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: c = _t2; // CHECK-NEXT: double _r_d2 = *_d_c; // CHECK-NEXT: *_d_c += _r_d2; -// CHECK-NEXT: double _r5 = _r_d2 * _t5; +// CHECK-NEXT: double _r5 = _r_d2 * i; // CHECK-NEXT: double _r6 = 3 * _r_d2; // CHECK-NEXT: * _d_i += _r6; // CHECK-NEXT: *_d_c -= _r_d2; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: b = _t1; // CHECK-NEXT: double _r_d1 = _d_b; // CHECK-NEXT: _d_b += _r_d1; -// CHECK-NEXT: double _r3 = _r_d1 * _t4; +// CHECK-NEXT: double _r3 = _r_d1 * i; // CHECK-NEXT: double _r4 = 2 * _r_d1; // CHECK-NEXT: * _d_i += _r4; // CHECK-NEXT: _d_b -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: a = _t0; // CHECK-NEXT: double _r_d0 = *_d_a; -// CHECK-NEXT: *_d_a += _r_d0 * _t2; -// CHECK-NEXT: double _r2 = _t3 * _r_d0; +// CHECK-NEXT: *_d_a += _r_d0 * i; +// CHECK-NEXT: double _r2 = a * _r_d0; // CHECK-NEXT: * _d_i += _r2; // CHECK-NEXT: *_d_a -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = _d_b * _t0; +// CHECK-NEXT: double _r0 = _d_b * j; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = _t1 * _d_b; +// CHECK-NEXT: double _r1 = i * _d_b; // CHECK-NEXT: * _d_j += _r1; // CHECK-NEXT: } // CHECK-NEXT: } @@ -708,26 +774,23 @@ double f16(double i, double j) { // CHECK-NEXT: double *_d_b = 0; // CHECK-NEXT: double *_d_c = 0; // CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; // CHECK-NEXT: _d_a = &* _d_i; // CHECK-NEXT: double &a = i; // CHECK-NEXT: _d_b = &*_d_a; // CHECK-NEXT: double &b = a; // CHECK-NEXT: _d_c = &*_d_b; // CHECK-NEXT: double &c = b; -// CHECK-NEXT: _t1 = c; -// CHECK-NEXT: _t2 = j; -// CHECK-NEXT: _t0 = 4 * _t2; -// CHECK-NEXT: c *= _t0; +// CHECK-NEXT: _t0 = c; +// CHECK-NEXT: c *= 4 * j; // CHECK-NEXT: goto _label0; -// CHECK-NEXT: _label0: +// CHECK-NEXT: _label0: // CHECK-NEXT: * _d_i += 1; // CHECK-NEXT: { +// CHECK-NEXT: c = _t0; // CHECK-NEXT: double _r_d0 = *_d_c; -// CHECK-NEXT: *_d_c += _r_d0 * _t0; -// CHECK-NEXT: double _r0 = _t1 * _r_d0; -// CHECK-NEXT: double _r1 = _r0 * _t2; +// CHECK-NEXT: *_d_c += _r_d0 * 4 * j; +// CHECK-NEXT: double _r0 = c * _r_d0; +// CHECK-NEXT: double _r1 = _r0 * j; // CHECK-NEXT: double _r2 = 4 * _r0; // CHECK-NEXT: * _d_j += _r2; // CHECK-NEXT: *_d_c -= _r_d0; @@ -743,14 +806,15 @@ double f17(double i, double j, double k) { // CHECK-NEXT: double _d_j = 0; // CHECK-NEXT: double _d_k = 0; // CHECK-NEXT: double _t0; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: j = 2 * _t0; +// CHECK-NEXT: _t0 = j; +// CHECK-NEXT: j = 2 * i; // CHECK-NEXT: goto _label0; -// CHECK-NEXT: _label0: +// CHECK-NEXT: _label0: // CHECK-NEXT: _d_j += 1; // CHECK-NEXT: { +// CHECK-NEXT: j = _t0; // CHECK-NEXT: double _r_d0 = _d_j; -// CHECK-NEXT: double _r0 = _r_d0 * _t0; +// CHECK-NEXT: double _r0 = _r_d0 * i; // CHECK-NEXT: double _r1 = 2 * _r_d0; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: _d_j -= _r_d0; @@ -767,25 +831,27 @@ double f18(double i, double j, double k) { // CHECK-NEXT: double _d_k = 0; // CHECK-NEXT: double _t0; // CHECK-NEXT: double _t1; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t1 = j; -// CHECK-NEXT: k = 2 * _t0 + 2 * _t1; +// CHECK-NEXT: _t0 = k; +// CHECK-NEXT: k = 2 * i + 2 * j; +// CHECK-NEXT: _t1 = k; // CHECK-NEXT: k += i; // CHECK-NEXT: goto _label0; -// CHECK-NEXT: _label0: +// CHECK-NEXT: _label0: // CHECK-NEXT: _d_k += 1; // CHECK-NEXT: { +// CHECK-NEXT: k = _t1; // CHECK-NEXT: double _r_d1 = _d_k; // CHECK-NEXT: _d_k += _r_d1; // CHECK-NEXT: * _d_i += _r_d1; // CHECK-NEXT: _d_k -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: k = _t0; // CHECK-NEXT: double _r_d0 = _d_k; -// CHECK-NEXT: double _r0 = _r_d0 * _t0; +// CHECK-NEXT: double _r0 = _r_d0 * i; // CHECK-NEXT: double _r1 = 2 * _r_d0; // CHECK-NEXT: * _d_i += _r1; -// CHECK-NEXT: double _r2 = _r_d0 * _t1; +// CHECK-NEXT: double _r2 = _r_d0 * j; // CHECK-NEXT: double _r3 = 2 * _r_d0; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: _d_k -= _r_d0; @@ -797,19 +863,13 @@ double f19(double a, double b) { } //CHECK: void f19_grad(double a, double b, clad::array_ref _d_a, clad::array_ref _d_b) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t0 = a; -//CHECK-NEXT: _t1 = b; -//CHECK-NEXT: _t2 = b; //CHECK-NEXT: goto _label0; -//CHECK-NEXT: _label0: +//CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: double _grad0 = 0.; //CHECK-NEXT: double _grad1 = 0.; //CHECK-NEXT: double _grad2 = 0.; -//CHECK-NEXT: clad::custom_derivatives::fma_pullback(_t0, _t1, _t2, 1, &_grad0, &_grad1, &_grad2); +//CHECK-NEXT: clad::custom_derivatives::fma_pullback(a, b, b, 1, &_grad0, &_grad1, &_grad2); //CHECK-NEXT: double _r0 = _grad0; //CHECK-NEXT: * _d_a += _r0; //CHECK-NEXT: double _r1 = _grad1; @@ -819,6 +879,65 @@ double f19(double a, double b) { //CHECK-NEXT: } //CHECK-NEXT: } +double f20(double x, double y) { + auto& r = x; + r = 3; + x = r * y; + return x; // 3y +} + +//CHECK: void f20_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { +//CHECK-NEXT: double *_d_r = 0; +//CHECK-NEXT: double _t0; +//CHECK-NEXT: double _t1; +//CHECK-NEXT: _d_r = &* _d_x; +//CHECK-NEXT: double &r = x; +//CHECK-NEXT: _t0 = r; +//CHECK-NEXT: r = 3; +//CHECK-NEXT: _t1 = x; +//CHECK-NEXT: x = r * y; +//CHECK-NEXT: goto _label0; +//CHECK-NEXT: _label0: +//CHECK-NEXT: * _d_x += 1; +//CHECK-NEXT: { +//CHECK-NEXT: x = _t1; +//CHECK-NEXT: double _r_d1 = * _d_x; +//CHECK-NEXT: double _r0 = _r_d1 * y; +//CHECK-NEXT: *_d_r += _r0; +//CHECK-NEXT: double _r1 = r * _r_d1; +//CHECK-NEXT: * _d_y += _r1; +//CHECK-NEXT: * _d_x -= _r_d1; +//CHECK-NEXT: * _d_x; +//CHECK-NEXT: } +//CHECK-NEXT: { +//CHECK-NEXT: r = _t0; +//CHECK-NEXT: double _r_d0 = *_d_r; +//CHECK-NEXT: *_d_r -= _r_d0; +//CHECK-NEXT: } +//CHECK-NEXT: } + +double f21 (double x, double y) { + y = (y++, x); + return y; +} + +//CHECK-NEXT: void f21_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { +//CHECK-NEXT: double _t0; +//CHECK-NEXT: _t0 = y; +//CHECK-NEXT: y = (y++ , x); +//CHECK-NEXT: goto _label0; +//CHECK-NEXT: _label0: +//CHECK-NEXT: * _d_y += 1; +//CHECK-NEXT: { +//CHECK-NEXT: y = _t0; +//CHECK-NEXT: double _r_d0 = * _d_y; +//CHECK-NEXT: * _d_y += 0; +//CHECK-NEXT: y--; +//CHECK-NEXT: * _d_x += _r_d0; +//CHECK-NEXT: * _d_y -= _r_d0; +//CHECK-NEXT: * _d_y; +//CHECK-NEXT: } +//CHECK-NEXT: } #define TEST(F, x, y) \ { \ @@ -881,4 +1000,6 @@ int main() { VAR_TEST(f17, "i", 3, 4, 5, &result[0]); // CHECK-EXEC: {2.00} VAR_TEST(f18, "i, j", 3, 4, 5, &result[0], &result[1]); // CHECK-EXEC: {3.00, 2.00} TEST(f19, 1, 2); // CHECK-EXEC: {2.00, 2.00} + TEST(f20, 1, 2); // CHECK-EXEC: {0.00, 3.00} + TEST(f21, 6, 4); // CHECK-EXEC: {1.00, 0.00} } diff --git a/test/Gradient/DiffInterface.C b/test/Gradient/DiffInterface.C index 6c245b710..45d31eea9 100644 --- a/test/Gradient/DiffInterface.C +++ b/test/Gradient/DiffInterface.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oGradientDiffInterface.out 2>&1 | FileCheck %s // RUN: ./GradientDiffInterface.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oGradientDiffInterface.out +// RUN: ./GradientDiffInterface.out | FileCheck -check-prefix=CHECK-EXEC %s #include "clad/Differentiator/Differentiator.h" @@ -13,22 +15,16 @@ double f_1(double x, double y, double z) { // all //CHECK: void f_1_grad(double x, double y, double z, clad::array_ref _d_x, clad::array_ref _d_y, clad::array_ref _d_z) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t2 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * x; //CHECK-NEXT: double _r1 = 0 * 1; //CHECK-NEXT: * _d_x += _r1; -//CHECK-NEXT: double _r2 = 1 * _t1; +//CHECK-NEXT: double _r2 = 1 * y; //CHECK-NEXT: double _r3 = 1 * 1; //CHECK-NEXT: * _d_y += _r3; -//CHECK-NEXT: double _r4 = 1 * _t2; +//CHECK-NEXT: double _r4 = 1 * z; //CHECK-NEXT: double _r5 = 2 * 1; //CHECK-NEXT: * _d_z += _r5; //CHECK-NEXT: } @@ -38,22 +34,16 @@ double f_1(double x, double y, double z) { //CHECK: void f_1_grad_0(double x, double y, double z, clad::array_ref _d_x) { //CHECK-NEXT: double _d_y = 0; //CHECK-NEXT: double _d_z = 0; -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t2 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * x; //CHECK-NEXT: double _r1 = 0 * 1; //CHECK-NEXT: * _d_x += _r1; -//CHECK-NEXT: double _r2 = 1 * _t1; +//CHECK-NEXT: double _r2 = 1 * y; //CHECK-NEXT: double _r3 = 1 * 1; //CHECK-NEXT: _d_y += _r3; -//CHECK-NEXT: double _r4 = 1 * _t2; +//CHECK-NEXT: double _r4 = 1 * z; //CHECK-NEXT: double _r5 = 2 * 1; //CHECK-NEXT: _d_z += _r5; //CHECK-NEXT: } @@ -63,22 +53,16 @@ double f_1(double x, double y, double z) { //CHECK: void f_1_grad_1(double x, double y, double z, clad::array_ref _d_y) { //CHECK-NEXT: double _d_x = 0; //CHECK-NEXT: double _d_z = 0; -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t2 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * x; //CHECK-NEXT: double _r1 = 0 * 1; //CHECK-NEXT: _d_x += _r1; -//CHECK-NEXT: double _r2 = 1 * _t1; +//CHECK-NEXT: double _r2 = 1 * y; //CHECK-NEXT: double _r3 = 1 * 1; //CHECK-NEXT: * _d_y += _r3; -//CHECK-NEXT: double _r4 = 1 * _t2; +//CHECK-NEXT: double _r4 = 1 * z; //CHECK-NEXT: double _r5 = 2 * 1; //CHECK-NEXT: _d_z += _r5; //CHECK-NEXT: } @@ -88,22 +72,16 @@ double f_1(double x, double y, double z) { //CHECK: void f_1_grad_2(double x, double y, double z, clad::array_ref _d_z) { //CHECK-NEXT: double _d_x = 0; //CHECK-NEXT: double _d_y = 0; -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t2 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * x; //CHECK-NEXT: double _r1 = 0 * 1; //CHECK-NEXT: _d_x += _r1; -//CHECK-NEXT: double _r2 = 1 * _t1; +//CHECK-NEXT: double _r2 = 1 * y; //CHECK-NEXT: double _r3 = 1 * 1; -//CHECK-NEXT: _d_y += _r3; -//CHECK-NEXT: double _r4 = 1 * _t2; +//CHECK-NEXT: _d_y += _r3; +//CHECK-NEXT: double _r4 = 1 * z; //CHECK-NEXT: double _r5 = 2 * 1; //CHECK-NEXT: * _d_z += _r5; //CHECK-NEXT: } @@ -112,22 +90,16 @@ double f_1(double x, double y, double z) { // x, y //CHECK: void f_1_grad_0_1(double x, double y, double z, clad::array_ref _d_x, clad::array_ref _d_y) { //CHECK-NEXT: double _d_z = 0; -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t2 = z; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * x; //CHECK-NEXT: double _r1 = 0 * 1; //CHECK-NEXT: * _d_x += _r1; -//CHECK-NEXT: double _r2 = 1 * _t1; +//CHECK-NEXT: double _r2 = 1 * y; //CHECK-NEXT: double _r3 = 1 * 1; //CHECK-NEXT: * _d_y += _r3; -//CHECK-NEXT: double _r4 = 1 * _t2; +//CHECK-NEXT: double _r4 = 1 * z; //CHECK-NEXT: double _r5 = 2 * 1; //CHECK-NEXT: _d_z += _r5; //CHECK-NEXT: } @@ -135,23 +107,17 @@ double f_1(double x, double y, double z) { // y, z //CHECK: void f_1_grad_1_2(double x, double y, double z, clad::array_ref _d_y, clad::array_ref _d_z) { -// CHECK-NEXT: double _d_x = 0; -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t2 = z; +//CHECK-NEXT: double _d_x = 0; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * x; //CHECK-NEXT: double _r1 = 0 * 1; -// CHECK-NEXT: _d_x += _r1; -//CHECK-NEXT: double _r2 = 1 * _t1; +//CHECK-NEXT: _d_x += _r1; +//CHECK-NEXT: double _r2 = 1 * y; //CHECK-NEXT: double _r3 = 1 * 1; //CHECK-NEXT: * _d_y += _r3; -//CHECK-NEXT: double _r4 = 1 * _t2; +//CHECK-NEXT: double _r4 = 1 * z; //CHECK-NEXT: double _r5 = 2 * 1; //CHECK-NEXT: * _d_z += _r5; //CHECK-NEXT: } diff --git a/test/Gradient/FunctionCalls.C b/test/Gradient/FunctionCalls.C index f3b6f6a2e..77dc2fb02 100644 --- a/test/Gradient/FunctionCalls.C +++ b/test/Gradient/FunctionCalls.C @@ -1,5 +1,7 @@ // RUN: %cladnumdiffclang -std=c++17 %s -I%S/../../include -oFunctionCalls.out 2>&1 | FileCheck %s // RUN: ./FunctionCalls.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladnumdiffclang -Xclang -plugin-arg-clad -Xclang -enable-tbr -std=c++17 %s -I%S/../../include -oFunctionCalls.out +// RUN: ./FunctionCalls.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -25,28 +27,22 @@ double fn1(float i) { } // CHECK: void fn1_grad(float i, clad::array_ref _d_i) { -// CHECK-NEXT: float _t0; // CHECK-NEXT: float _d_res = 0; -// CHECK-NEXT: float _t1; -// CHECK-NEXT: float _t2; // CHECK-NEXT: double _d_a = 0; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: float res = A::constantFn(_t0); -// CHECK-NEXT: _t2 = res; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: double a = _t2 * _t1; +// CHECK-NEXT: float res = A::constantFn(i); +// CHECK-NEXT: double a = res * i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_a += 1; // CHECK-NEXT: { -// CHECK-NEXT: double _r1 = _d_a * _t1; +// CHECK-NEXT: double _r1 = _d_a * i; // CHECK-NEXT: _d_res += _r1; -// CHECK-NEXT: double _r2 = _t2 * _d_a; +// CHECK-NEXT: double _r2 = res * _d_a; // CHECK-NEXT: * _d_i += _r2; // CHECK-NEXT: } // CHECK-NEXT: { // CHECK-NEXT: float _grad0 = 0.F; -// CHECK-NEXT: constantFn_pullback(_t0, _d_res, &_grad0); +// CHECK-NEXT: constantFn_pullback(i, _d_res, &_grad0); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_i += _r0; // CHECK-NEXT: } @@ -60,8 +56,12 @@ double modify1(double& i, double& j) { } // CHECK: void modify1_pullback(double &i, double &j, double _d_y, clad::array_ref _d_i, clad::array_ref _d_j) { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: double _t1; // CHECK-NEXT: double _d_res = 0; +// CHECK-NEXT: _t0 = i; // CHECK-NEXT: i += j; +// CHECK-NEXT: _t1 = j; // CHECK-NEXT: j += j; // CHECK-NEXT: double res = i + j; // CHECK-NEXT: goto _label0; @@ -72,6 +72,7 @@ double modify1(double& i, double& j) { // CHECK-NEXT: * _d_j += _d_res; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: j = _t1; // CHECK-NEXT: double _r_d1 = * _d_j; // CHECK-NEXT: * _d_j += _r_d1; // CHECK-NEXT: * _d_j += _r_d1; @@ -79,6 +80,7 @@ double modify1(double& i, double& j) { // CHECK-NEXT: * _d_j; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: i = _t0; // CHECK-NEXT: double _r_d0 = * _d_i; // CHECK-NEXT: * _d_i += _r_d0; // CHECK-NEXT: * _d_j += _r_d0; @@ -100,26 +102,36 @@ double fn2(double i, double j) { // CHECK-NEXT: double _t1; // CHECK-NEXT: double _t2; // CHECK-NEXT: double _t3; +// CHECK-NEXT: double _t4; +// CHECK-NEXT: double _t5; // CHECK-NEXT: double temp = 0; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t1 = j; +// CHECK-NEXT: _t0 = temp; +// CHECK-NEXT: _t1 = i; +// CHECK-NEXT: _t2 = j; // CHECK-NEXT: temp = modify1(i, j); -// CHECK-NEXT: _t2 = i; -// CHECK-NEXT: _t3 = j; +// CHECK-NEXT: _t3 = temp; +// CHECK-NEXT: _t4 = i; +// CHECK-NEXT: _t5 = j; // CHECK-NEXT: temp = modify1(i, j); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: * _d_i += 1; // CHECK-NEXT: { +// CHECK-NEXT: temp = _t3; // CHECK-NEXT: double _r_d1 = _d_temp; -// CHECK-NEXT: modify1_pullback(_t2, _t3, _r_d1, &* _d_i, &* _d_j); +// CHECK-NEXT: i = _t4; +// CHECK-NEXT: j = _t5; +// CHECK-NEXT: modify1_pullback(_t4, _t5, _r_d1, &* _d_i, &* _d_j); // CHECK-NEXT: double _r2 = * _d_i; // CHECK-NEXT: double _r3 = * _d_j; // CHECK-NEXT: _d_temp -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: temp = _t0; // CHECK-NEXT: double _r_d0 = _d_temp; -// CHECK-NEXT: modify1_pullback(_t0, _t1, _r_d0, &* _d_i, &* _d_j); +// CHECK-NEXT: i = _t1; +// CHECK-NEXT: j = _t2; +// CHECK-NEXT: modify1_pullback(_t1, _t2, _r_d0, &* _d_i, &* _d_j); // CHECK-NEXT: double _r0 = * _d_i; // CHECK-NEXT: double _r1 = * _d_j; // CHECK-NEXT: _d_temp -= _r_d0; @@ -132,9 +144,14 @@ void update1(double& i, double& j) { } // CHECK: void update1_pullback(double &i, double &j, clad::array_ref _d_i, clad::array_ref _d_j) { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: double _t1; +// CHECK-NEXT: _t0 = i; // CHECK-NEXT: i += j; +// CHECK-NEXT: _t1 = j; // CHECK-NEXT: j += j; // CHECK-NEXT: { +// CHECK-NEXT: j = _t1; // CHECK-NEXT: double _r_d1 = * _d_j; // CHECK-NEXT: * _d_j += _r_d1; // CHECK-NEXT: * _d_j += _r_d1; @@ -142,6 +159,7 @@ void update1(double& i, double& j) { // CHECK-NEXT: * _d_j; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: i = _t0; // CHECK-NEXT: double _r_d0 = * _d_i; // CHECK-NEXT: * _d_i += _r_d0; // CHECK-NEXT: * _d_j += _r_d0; @@ -171,11 +189,15 @@ double fn3(double i, double j) { // CHECK-NEXT: _label0: // CHECK-NEXT: * _d_i += 1; // CHECK-NEXT: { +// CHECK-NEXT: i = _t2; +// CHECK-NEXT: j = _t3; // CHECK-NEXT: update1_pullback(_t2, _t3, &* _d_i, &* _d_j); // CHECK-NEXT: double _r2 = * _d_i; // CHECK-NEXT: double _r3 = * _d_j; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: i = _t0; +// CHECK-NEXT: j = _t1; // CHECK-NEXT: update1_pullback(_t0, _t1, &* _d_i, &* _d_j); // CHECK-NEXT: double _r0 = * _d_i; // CHECK-NEXT: double _r1 = * _d_j; @@ -194,33 +216,36 @@ float sum(double* arr, int n) { // CHECK-NEXT: float _d_res = 0; // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: double _t3; +// CHECK-NEXT: clad::tape _t1 = {}; +// CHECK-NEXT: double _t2; // CHECK-NEXT: float res = 0; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: for (int i = 0; i < n; ++i) { // CHECK-NEXT: _t0++; -// CHECK-NEXT: res += arr[clad::push(_t1, i)]; +// CHECK-NEXT: clad::push(_t1, res); +// CHECK-NEXT: res += arr[i]; // CHECK-NEXT: } -// CHECK-NEXT: _t3 = arr[0]; -// CHECK-NEXT: arr[0] += 10 * _t3; +// CHECK-NEXT: _t2 = arr[0]; +// CHECK-NEXT: arr[0] += 10 * arr[0]; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += _d_y; // CHECK-NEXT: { +// CHECK-NEXT: arr[0] = _t2; // CHECK-NEXT: double _r_d1 = _d_arr[0]; // CHECK-NEXT: _d_arr[0] += _r_d1; -// CHECK-NEXT: double _r0 = _r_d1 * _t3; +// CHECK-NEXT: double _r0 = _r_d1 * arr[0]; // CHECK-NEXT: double _r1 = 10 * _r_d1; // CHECK-NEXT: _d_arr[0] += _r1; // CHECK-NEXT: _d_arr[0] -= _r_d1; // CHECK-NEXT: _d_arr[0]; // CHECK-NEXT: } // CHECK-NEXT: for (; _t0; _t0--) { +// CHECK-NEXT: --i; +// CHECK-NEXT: res = clad::pop(_t1); // CHECK-NEXT: float _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; -// CHECK-NEXT: int _t2 = clad::pop(_t1); -// CHECK-NEXT: _d_arr[_t2] += _r_d0; +// CHECK-NEXT: _d_arr[i] += _r_d0; // CHECK-NEXT: _d_res -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: } @@ -232,10 +257,11 @@ void twice(double& d) { // CHECK: void twice_pullback(double &d, clad::array_ref _d_d) { // CHECK-NEXT: double _t0; // CHECK-NEXT: _t0 = d; -// CHECK-NEXT: d = 2 * _t0; +// CHECK-NEXT: d = 2 * d; // CHECK-NEXT: { +// CHECK-NEXT: d = _t0; // CHECK-NEXT: double _r_d0 = * _d_d; -// CHECK-NEXT: double _r0 = _r_d0 * _t0; +// CHECK-NEXT: double _r0 = _r_d0 * d; // CHECK-NEXT: double _r1 = 2 * _r_d0; // CHECK-NEXT: * _d_d += _r1; // CHECK-NEXT: * _d_d -= _r_d0; @@ -255,49 +281,50 @@ double fn4(double* arr, int n) { // CHECK: void fn4_grad(double *arr, int n, clad::array_ref _d_arr, clad::array_ref _d_n) { // CHECK-NEXT: double _d_res = 0; -// CHECK-NEXT: double *_t0; -// CHECK-NEXT: int _t1; +// CHECK-NEXT: double _t0; +// CHECK-NEXT: double *_t1; // CHECK-NEXT: unsigned long _t2; // CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: clad::tape _t3 = {}; -// CHECK-NEXT: clad::tape _t5 = {}; -// CHECK-NEXT: clad::tape _t6 = {}; -// CHECK-NEXT: clad::tape _t8 = {}; +// CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: clad::tape _t4 = {}; // CHECK-NEXT: double res = 0; -// CHECK-NEXT: _t0 = arr; -// CHECK-NEXT: _t1 = n; -// CHECK-NEXT: res += sum(arr, _t1); +// CHECK-NEXT: _t0 = res; +// CHECK-NEXT: _t1 = arr; +// CHECK-NEXT: res += sum(arr, n); // CHECK-NEXT: _t2 = 0; // CHECK-NEXT: for (int i = 0; i < n; ++i) { // CHECK-NEXT: _t2++; -// CHECK-NEXT: clad::push(_t5, arr[clad::push(_t3, i)]); -// CHECK-NEXT: twice(arr[clad::push(_t6, i)]); -// CHECK-NEXT: res += arr[clad::push(_t8, i)]; +// CHECK-NEXT: clad::push(_t3, arr[i]); +// CHECK-NEXT: twice(arr[i]); +// CHECK-NEXT: clad::push(_t4, res); +// CHECK-NEXT: res += arr[i]; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: for (; _t2; _t2--) { +// CHECK-NEXT: --i; // CHECK-NEXT: { -// CHECK-NEXT: int _t7 = clad::pop(_t6); -// CHECK-NEXT: int _t4 = clad::pop(_t3); +// CHECK-NEXT: res = clad::pop(_t4); // CHECK-NEXT: double _r_d1 = _d_res; // CHECK-NEXT: _d_res += _r_d1; -// CHECK-NEXT: int _t9 = clad::pop(_t8); -// CHECK-NEXT: _d_arr[_t9] += _r_d1; +// CHECK-NEXT: _d_arr[i] += _r_d1; // CHECK-NEXT: _d_res -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: double _r3 = clad::pop(_t5); -// CHECK-NEXT: twice_pullback(_r3, &_d_arr[_t4]); -// CHECK-NEXT: double _r2 = _d_arr[_t4]; +// CHECK-NEXT: double _r3 = clad::pop(_t3); +// CHECK-NEXT: arr[i] = _r3; +// CHECK-NEXT: twice_pullback(_r3, &_d_arr[i]); +// CHECK-NEXT: double _r2 = _d_arr[i]; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: res = _t0; // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; +// CHECK-NEXT: arr = _t1; // CHECK-NEXT: int _grad1 = 0; -// CHECK-NEXT: sum_pullback(_t0, _t1, _r_d0, _d_arr, &_grad1); +// CHECK-NEXT: sum_pullback(_t1, n, _r_d0, _d_arr, &_grad1); // CHECK-NEXT: clad::array _r0(_d_arr); // CHECK-NEXT: int _r1 = _grad1; // CHECK-NEXT: * _d_n += _r1; @@ -313,13 +340,14 @@ double modify2(double* arr) { // CHECK: void modify2_pullback(double *arr, double _d_y, clad::array_ref _d_arr) { // CHECK-NEXT: double _t0; // CHECK-NEXT: _t0 = arr[0]; -// CHECK-NEXT: arr[0] = 5 * _t0 + arr[1]; +// CHECK-NEXT: arr[0] = 5 * arr[0] + arr[1]; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: arr[0] = _t0; // CHECK-NEXT: double _r_d0 = _d_arr[0]; -// CHECK-NEXT: double _r0 = _r_d0 * _t0; +// CHECK-NEXT: double _r0 = _r_d0 * arr[0]; // CHECK-NEXT: double _r1 = 5 * _r_d0; // CHECK-NEXT: _d_arr[0] += _r1; // CHECK-NEXT: _d_arr[1] += _r_d0; @@ -342,6 +370,7 @@ double fn5(double* arr, int n) { // CHECK-NEXT: _label0: // CHECK-NEXT: _d_arr[0] += 1; // CHECK-NEXT: { +// CHECK-NEXT: arr = _t0; // CHECK-NEXT: modify2_pullback(_t0, _d_temp, _d_arr); // CHECK-NEXT: clad::array _r0(_d_arr); // CHECK-NEXT: } @@ -371,29 +400,28 @@ double fn7(double i, double j) { } // CHECK: void fn6_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t0 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; +// CHECK-NEXT: double _r0 = 1 * j; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = _t1 * 1; +// CHECK-NEXT: double _r1 = i * 1; // CHECK-NEXT: * _d_j += _r1; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: void identity_pullback(double &i, double _d_y, clad::array_ref _d_i) { // CHECK-NEXT: double _d__d_i = 0; +// CHECK-NEXT: double _t0; // CHECK-NEXT: MyStruct::myFunction(); // CHECK-NEXT: double _d_i0 = i; +// CHECK-NEXT: _t0 = _d_i0; // CHECK-NEXT: _d_i0 += 1; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: * _d_i += _d_y; // CHECK-NEXT: { +// CHECK-NEXT: _d_i0 = _t0; // CHECK-NEXT: double _r_d0 = _d__d_i; // CHECK-NEXT: _d__d_i += _r_d0; // CHECK-NEXT: _d__d_i -= _r_d0; @@ -403,8 +431,10 @@ double fn7(double i, double j) { // CHECK: clad::ValueAndAdjoint identity_forw(double &i, clad::array_ref _d_i) { // CHECK-NEXT: double _d__d_i = 0; +// CHECK-NEXT: double _t0; // CHECK-NEXT: MyStruct::myFunction(); // CHECK-NEXT: double _d_i0 = i; +// CHECK-NEXT: _t0 = _d_i0; // CHECK-NEXT: _d_i0 += 1; // CHECK-NEXT: return {i, * _d_i}; // CHECK-NEXT: } @@ -424,10 +454,10 @@ double fn7(double i, double j) { // CHECK-NEXT: clad::ValueAndAdjoint _t3 = identity_forw(j, &* _d_j); // CHECK-NEXT: _d_l = &_t3.adjoint; // CHECK-NEXT: double &l = _t3.value; -// CHECK-NEXT: _t4 = j; -// CHECK-NEXT: k += 7 * _t4; -// CHECK-NEXT: _t5 = i; -// CHECK-NEXT: l += 9 * _t5; +// CHECK-NEXT: _t4 = k; +// CHECK-NEXT: k += 7 * j; +// CHECK-NEXT: _t5 = l; +// CHECK-NEXT: l += 9 * i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { @@ -435,26 +465,30 @@ double fn7(double i, double j) { // CHECK-NEXT: * _d_j += 1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: l = _t5; // CHECK-NEXT: double _r_d1 = *_d_l; // CHECK-NEXT: *_d_l += _r_d1; -// CHECK-NEXT: double _r4 = _r_d1 * _t5; +// CHECK-NEXT: double _r4 = _r_d1 * i; // CHECK-NEXT: double _r5 = 9 * _r_d1; // CHECK-NEXT: * _d_i += _r5; // CHECK-NEXT: *_d_l -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: k = _t4; // CHECK-NEXT: double _r_d0 = *_d_k; // CHECK-NEXT: *_d_k += _r_d0; -// CHECK-NEXT: double _r2 = _r_d0 * _t4; +// CHECK-NEXT: double _r2 = _r_d0 * j; // CHECK-NEXT: double _r3 = 7 * _r_d0; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: *_d_k -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: j = _t2; // CHECK-NEXT: identity_pullback(_t2, 0, &* _d_j); // CHECK-NEXT: double _r1 = * _d_j; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: i = _t0; // CHECK-NEXT: identity_pullback(_t0, 0, &* _d_i); // CHECK-NEXT: double _r0 = * _d_i; // CHECK-NEXT: } @@ -467,27 +501,19 @@ double fn8(double x, double y) { // CHECK: void fn8_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { // CHECK-NEXT: double _t0; // CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: double _t5; -// CHECK-NEXT: _t3 = x; -// CHECK-NEXT: _t2 = y; -// CHECK-NEXT: _t4 = _t3 * _t2; // CHECK-NEXT: _t1 = std::tanh(1.); -// CHECK-NEXT: _t5 = _t4 * _t1; // CHECK-NEXT: _t0 = std::max(1., 2.); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: double _r0 = 1 * _t0; // CHECK-NEXT: double _r1 = _r0 * _t1; -// CHECK-NEXT: double _r2 = _r1 * _t2; +// CHECK-NEXT: double _r2 = _r1 * y; // CHECK-NEXT: * _d_x += _r2; -// CHECK-NEXT: double _r3 = _t3 * _r1; +// CHECK-NEXT: double _r3 = x * _r1; // CHECK-NEXT: * _d_y += _r3; -// CHECK-NEXT: double _r4 = _t4 * _r0; -// CHECK-NEXT: double _r5 = _t5 * 1; +// CHECK-NEXT: double _r4 = x * y * _r0; +// CHECK-NEXT: double _r5 = x * y * _t1 * 1; // CHECK-NEXT: } // CHECK-NEXT: } @@ -510,24 +536,19 @@ double fn9(double x, double y) { return custom_max(x*y, y); } -// CHECK: void fn9_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { +// CHECK:void fn9_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { // CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: _t1 = x; // CHECK-NEXT: _t0 = y; -// CHECK-NEXT: _t2 = _t1 * _t0; -// CHECK-NEXT: _t3 = y; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { +// CHECK-NEXT: y = _t0; // CHECK-NEXT: double _grad0 = 0.; -// CHECK-NEXT: custom_max_pullback(_t2, _t3, 1, &_grad0, &* _d_y); +// CHECK-NEXT: custom_max_pullback(x * y, _t0, 1, &_grad0, &* _d_y); // CHECK-NEXT: double _r0 = _grad0; -// CHECK-NEXT: double _r1 = _r0 * _t0; +// CHECK-NEXT: double _r1 = _r0 * y; // CHECK-NEXT: * _d_x += _r1; -// CHECK-NEXT: double _r2 = _t1 * _r0; +// CHECK-NEXT: double _r2 = x * _r0; // CHECK-NEXT: * _d_y += _r2; // CHECK-NEXT: double _r3 = * _d_y; // CHECK-NEXT: } @@ -548,45 +569,53 @@ double fn10(double x, double y) { // CHECK-NEXT: double _t2; // CHECK-NEXT: double _t3; // CHECK-NEXT: double _t4; +// CHECK-NEXT: double _t5; // CHECK-NEXT: double out = x; // CHECK-NEXT: _t0 = out; -// CHECK-NEXT: out = std::max(out, 0.); // CHECK-NEXT: _t1 = out; -// CHECK-NEXT: out = std::min(out, 10.); +// CHECK-NEXT: out = std::max(out, 0.); // CHECK-NEXT: _t2 = out; -// CHECK-NEXT: out = std::clamp(out, 3., 7.); +// CHECK-NEXT: _t3 = out; +// CHECK-NEXT: out = std::min(out, 10.); // CHECK-NEXT: _t4 = out; -// CHECK-NEXT: _t3 = y; +// CHECK-NEXT: _t5 = out; +// CHECK-NEXT: out = std::clamp(out, 3., 7.); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r7 = 1 * _t3; +// CHECK-NEXT: double _r7 = 1 * y; // CHECK-NEXT: _d_out += _r7; -// CHECK-NEXT: double _r8 = _t4 * 1; +// CHECK-NEXT: double _r8 = out * 1; // CHECK-NEXT: * _d_y += _r8; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: out = _t4; // CHECK-NEXT: double _r_d2 = _d_out; +// CHECK-NEXT: out = _t5; // CHECK-NEXT: double _grad5 = 0.; // CHECK-NEXT: double _grad6 = 0.; -// CHECK-NEXT: clad::custom_derivatives::std::clamp_pullback(_t2, 3., 7., _r_d2, &_d_out, &_grad5, &_grad6); +// CHECK-NEXT: clad::custom_derivatives::std::clamp_pullback(_t5, 3., 7., _r_d2, &_d_out, &_grad5, &_grad6); // CHECK-NEXT: double _r4 = _d_out; // CHECK-NEXT: double _r5 = _grad5; // CHECK-NEXT: double _r6 = _grad6; // CHECK-NEXT: _d_out -= _r_d2; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: out = _t2; // CHECK-NEXT: double _r_d1 = _d_out; +// CHECK-NEXT: out = _t3; // CHECK-NEXT: double _grad3 = 0.; -// CHECK-NEXT: clad::custom_derivatives::std::min_pullback(_t1, 10., _r_d1, &_d_out, &_grad3); +// CHECK-NEXT: clad::custom_derivatives::std::min_pullback(_t3, 10., _r_d1, &_d_out, &_grad3); // CHECK-NEXT: double _r2 = _d_out; // CHECK-NEXT: double _r3 = _grad3; // CHECK-NEXT: _d_out -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: out = _t0; // CHECK-NEXT: double _r_d0 = _d_out; +// CHECK-NEXT: out = _t1; // CHECK-NEXT: double _grad1 = 0.; -// CHECK-NEXT: clad::custom_derivatives::std::max_pullback(_t0, 0., _r_d0, &_d_out, &_grad1); +// CHECK-NEXT: clad::custom_derivatives::std::max_pullback(_t1, 0., _r_d0, &_d_out, &_grad1); // CHECK-NEXT: double _r0 = _d_out; // CHECK-NEXT: double _r1 = _grad1; // CHECK-NEXT: _d_out -= _r_d0; @@ -627,6 +656,8 @@ double fn11(double x, double y) { // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { +// CHECK-NEXT: x = _t0; +// CHECK-NEXT: y = _t1; // CHECK-NEXT: clad::custom_derivatives::n1::sum_pullback(_t0, _t1, 1, &* _d_x, &* _d_y); // CHECK-NEXT: double _r0 = * _d_x; // CHECK-NEXT: double _r1 = * _d_y; diff --git a/test/Gradient/Functors.C b/test/Gradient/Functors.C index e663fe409..6d65ba252 100644 --- a/test/Gradient/Functors.C +++ b/test/Gradient/Functors.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oFunctors.out 2>&1 | FileCheck %s // RUN: ./Functors.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oFunctors.out +// RUN: ./Functors.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" @@ -13,23 +15,15 @@ struct Experiment { Experiment& operator=(const Experiment& E) = default; // CHECK: void operator_call_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t2 = this->x; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t3 = _t2 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: (* _d_this).x += _r1; - // CHECK-NEXT: double _r2 = _t2 * _r0; + // CHECK-NEXT: double _r2 = this->x * _r0; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = this->x * i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -42,25 +36,16 @@ struct ExperimentConst { void setX(double val) const { x = val; } ExperimentConst& operator=(const ExperimentConst& E) = default; - // CHECK: void operator_call_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t2 = this->x; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t3 = _t2 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: (* _d_this).x += _r1; - // CHECK-NEXT: double _r2 = _t2 * _r0; + // CHECK-NEXT: double _r2 = this->x * _r0; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = this->x * i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -80,23 +65,15 @@ struct ExperimentVolatile { }; // CHECK: void operator_call_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: volatile double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t2 = this->x; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t3 = _t2 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: (* _d_this).x += _r1; - // CHECK-NEXT: double _r2 = _t2 * _r0; + // CHECK-NEXT: double _r2 = this->x * _r0; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = this->x * i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -116,23 +93,15 @@ struct ExperimentConstVolatile { }; // CHECK: void operator_call_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: volatile double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t2 = this->x; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t3 = _t2 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: (* _d_this).x += _r1; - // CHECK-NEXT: double _r2 = _t2 * _r0; + // CHECK-NEXT: double _r2 = this->x * _r0; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = this->x * i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -149,23 +118,15 @@ struct ExperimentNNS { ExperimentNNS& operator=(const ExperimentNNS& E) = default; // CHECK: void operator_call_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t2 = this->x; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t3 = _t2 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: (* _d_this).x += _r1; - // CHECK-NEXT: double _r2 = _t2 * _r0; + // CHECK-NEXT: double _r2 = this->x * _r0; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = this->x * i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -225,23 +186,15 @@ int main() { auto lambda = [](double i, double j) { return i * i * j; }; // CHECK: inline void operator_call_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) const { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t2 = i; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t3 = _t2 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = _t2 * _r0; + // CHECK-NEXT: double _r2 = i * _r0; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -249,22 +202,14 @@ int main() { auto lambdaWithCapture = [&](double ii, double j) { return x * ii * j; }; // CHECK: inline void operator_call_grad(double ii, double j, clad::array_ref _d_ii, clad::array_ref _d_j) const { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t2 = x; - // CHECK-NEXT: _t1 = ii; - // CHECK-NEXT: _t3 = _t2 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; - // CHECK-NEXT: double _r2 = _t2 * _r0; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * ii; + // CHECK-NEXT: double _r2 = x * _r0; // CHECK-NEXT: * _d_ii += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = x * ii * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -319,19 +264,15 @@ int main() { // CHECK: void CallFunctor_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { // CHECK-NEXT: Experiment _d_E({}); - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: Experiment _t2; + // CHECK-NEXT: Experiment _t0; // CHECK-NEXT: Experiment E(3, 5); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t1 = j; - // CHECK-NEXT: _t2 = E; + // CHECK-NEXT: _t0 = E; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: double _grad0 = 0.; // CHECK-NEXT: double _grad1 = 0.; - // CHECK-NEXT: _t2.operator_call_pullback(_t0, _t1, 1, &_d_E, &_grad0, &_grad1); + // CHECK-NEXT: _t0.operator_call_pullback(i, j, 1, &_d_E, &_grad0, &_grad1); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: * _d_i += _r0; // CHECK-NEXT: double _r1 = _grad1; @@ -346,18 +287,14 @@ int main() { printf("%.2f %.2f\n", di, dj); // CHECK-EXEC: 27.00 21.00 // CHECK: void FunctorAsArg_grad(Experiment fn, double i, double j, clad::array_ref _d_fn, clad::array_ref _d_i, clad::array_ref _d_j) { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: Experiment _t2; - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t1 = j; - // CHECK-NEXT: _t2 = fn; + // CHECK-NEXT: Experiment _t0; + // CHECK-NEXT: _t0 = fn; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: double _grad0 = 0.; // CHECK-NEXT: double _grad1 = 0.; - // CHECK-NEXT: _t2.operator_call_pullback(_t0, _t1, 1, &(* _d_fn), &_grad0, &_grad1); + // CHECK-NEXT: _t0.operator_call_pullback(i, j, 1, &(* _d_fn), &_grad0, &_grad1); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: * _d_i += _r0; // CHECK-NEXT: double _r1 = _grad1; @@ -373,18 +310,14 @@ int main() { printf("%.2f %.2f\n", di, dj); // CHECK-EXEC: 27.00 21.00 // CHECK: void FunctorAsArg_pullback(Experiment fn, double i, double j, double _d_y, clad::array_ref _d_fn, clad::array_ref _d_i, clad::array_ref _d_j) { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: Experiment _t2; - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t1 = j; - // CHECK-NEXT: _t2 = fn; + // CHECK-NEXT: Experiment _t0; + // CHECK-NEXT: _t0 = fn; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: double _grad0 = 0.; // CHECK-NEXT: double _grad1 = 0.; - // CHECK-NEXT: _t2.operator_call_pullback(_t0, _t1, _d_y, &(* _d_fn), &_grad0, &_grad1); + // CHECK-NEXT: _t0.operator_call_pullback(i, j, _d_y, &(* _d_fn), &_grad0, &_grad1); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: * _d_i += _r0; // CHECK-NEXT: double _r1 = _grad1; @@ -394,20 +327,14 @@ int main() { // CHECK: void FunctorAsArgWrapper_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { // CHECK-NEXT: Experiment _d_E({}); - // CHECK-NEXT: Experiment _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; // CHECK-NEXT: Experiment E(3, 5); - // CHECK-NEXT: _t0 = E - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: Experiment _grad0; // CHECK-NEXT: double _grad1 = 0.; // CHECK-NEXT: double _grad2 = 0.; - // CHECK-NEXT: FunctorAsArg_pullback(_t0, _t1, _t2, 1, &_grad0, &_grad1, &_grad2); + // CHECK-NEXT: FunctorAsArg_pullback(E, i, j, 1, &_grad0, &_grad1, &_grad2); // CHECK-NEXT: Experiment _r0(_grad0); // CHECK-NEXT: double _r1 = _grad1; // CHECK-NEXT: * _d_i += _r1; diff --git a/test/Gradient/Gradients.C b/test/Gradient/Gradients.C index 8ac9fed7d..6b91514ec 100644 --- a/test/Gradient/Gradients.C +++ b/test/Gradient/Gradients.C @@ -1,5 +1,7 @@ // RUN: %cladnumdiffclang %s -I%S/../../include -oGradients.out 2>&1 | FileCheck %s // RUN: ./Gradients.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladnumdiffclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oGradients.out +// RUN: ./Gradients.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -30,17 +32,13 @@ double f_add2(double x, double y) { } //CHECK: void f_add2_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * x; //CHECK-NEXT: double _r1 = 3 * 1; //CHECK-NEXT: * _d_x += _r1; -//CHECK-NEXT: double _r2 = 1 * _t1; +//CHECK-NEXT: double _r2 = 1 * y; //CHECK-NEXT: double _r3 = 4 * 1; //CHECK-NEXT: * _d_y += _r3; //CHECK-NEXT: } @@ -53,18 +51,14 @@ double f_add3(double x, double y) { } //CHECK: void f_add3_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * x; //CHECK-NEXT: double _r1 = 3 * 1; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: double _r2 = 1 * 4; -//CHECK-NEXT: double _r3 = _r2 * _t1; +//CHECK-NEXT: double _r3 = _r2 * y; //CHECK-NEXT: double _r4 = 4 * _r2; //CHECK-NEXT: * _d_y += _r4; //CHECK-NEXT: } @@ -91,17 +85,13 @@ double f_sub2(double x, double y) { } //CHECK: void f_sub2_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * x; //CHECK-NEXT: double _r1 = 3 * 1; //CHECK-NEXT: * _d_x += _r1; -//CHECK-NEXT: double _r2 = -1 * _t1; +//CHECK-NEXT: double _r2 = -1 * y; //CHECK-NEXT: double _r3 = 4 * -1; //CHECK-NEXT: * _d_y += _r3; //CHECK-NEXT: } @@ -114,16 +104,12 @@ double f_mult1(double x, double y) { } //CHECK: void f_mult1_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * y; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * 1; +//CHECK-NEXT: double _r1 = x * 1; //CHECK-NEXT: * _d_y += _r1; //CHECK-NEXT: } //CHECK-NEXT: } @@ -135,21 +121,15 @@ double f_mult2(double x, double y) { } //CHECK: void f_mult2_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t2 = 3 * _t1 * 4; -//CHECK-NEXT: _t0 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * y; //CHECK-NEXT: double _r1 = _r0 * 4; -//CHECK-NEXT: double _r2 = _r1 * _t1; +//CHECK-NEXT: double _r2 = _r1 * x; //CHECK-NEXT: double _r3 = 3 * _r1; //CHECK-NEXT: * _d_x += _r3; -//CHECK-NEXT: double _r4 = _t2 * 1; +//CHECK-NEXT: double _r4 = 3 * x * 4 * 1; //CHECK-NEXT: * _d_y += _r4; //CHECK-NEXT: } //CHECK-NEXT: } @@ -162,15 +142,13 @@ double f_div1(double x, double y) { //CHECK: void f_div1_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { //CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: _t1 = x; //CHECK-NEXT: _t0 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: double _r0 = 1 / _t0; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = 1 * -_t1 / (_t0 * _t0); +//CHECK-NEXT: double _r1 = 1 * -x / (_t0 * _t0); //CHECK-NEXT: * _d_y += _r1; //CHECK-NEXT: } //CHECK-NEXT: } @@ -183,22 +161,16 @@ double f_div2(double x, double y) { //CHECK: void f_div2_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { //CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t2 = 3 * _t1; -//CHECK-NEXT: _t3 = y; -//CHECK-NEXT: _t0 = (4 * _t3); +//CHECK-NEXT: _t0 = (4 * y); //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: double _r0 = 1 / _t0; -//CHECK-NEXT: double _r1 = _r0 * _t1; +//CHECK-NEXT: double _r1 = _r0 * x; //CHECK-NEXT: double _r2 = 3 * _r0; //CHECK-NEXT: * _d_x += _r2; -//CHECK-NEXT: double _r3 = 1 * -_t2 / (_t0 * _t0); -//CHECK-NEXT: double _r4 = _r3 * _t3; +//CHECK-NEXT: double _r3 = 1 * -3 * x / (_t0 * _t0); +//CHECK-NEXT: double _r4 = _r3 * y; //CHECK-NEXT: double _r5 = 4 * _r3; //CHECK-NEXT: * _d_y += _r5; //CHECK-NEXT: } @@ -212,39 +184,25 @@ double f_c(double x, double y) { //CHECK: void f_c_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { //CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: _t1 = -x; //CHECK-NEXT: _t0 = y; -//CHECK-NEXT: _t3 = (x + y); -//CHECK-NEXT: _t5 = x; -//CHECK-NEXT: _t4 = y; -//CHECK-NEXT: _t2 = (_t5 / _t4); -//CHECK-NEXT: _t7 = x; -//CHECK-NEXT: _t6 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * y; //CHECK-NEXT: * _d_x += -_r0; -//CHECK-NEXT: double _r1 = _t1 * 1; +//CHECK-NEXT: double _r1 = -x * 1; //CHECK-NEXT: * _d_y += _r1; -//CHECK-NEXT: double _r2 = 1 * _t2; +//CHECK-NEXT: double _r2 = 1 * (x / y); //CHECK-NEXT: * _d_x += _r2; //CHECK-NEXT: * _d_y += _r2; -//CHECK-NEXT: double _r3 = _t3 * 1; -//CHECK-NEXT: double _r4 = _r3 / _t4; +//CHECK-NEXT: double _r3 = (x + y) * 1; +//CHECK-NEXT: double _r4 = _r3 / _t0; //CHECK-NEXT: * _d_x += _r4; -//CHECK-NEXT: double _r5 = _r3 * -_t5 / (_t4 * _t4); +//CHECK-NEXT: double _r5 = _r3 * -x / (_t0 * _t0); //CHECK-NEXT: * _d_y += _r5; -//CHECK-NEXT: double _r6 = -1 * _t6; +//CHECK-NEXT: double _r6 = -1 * x; //CHECK-NEXT: * _d_x += _r6; -//CHECK-NEXT: double _r7 = _t7 * -1; +//CHECK-NEXT: double _r7 = x * -1; //CHECK-NEXT: * _d_x += _r7; //CHECK-NEXT: } //CHECK-NEXT: } @@ -256,44 +214,26 @@ double f_rosenbrock(double x, double y) { } //CHECK: void f_rosenbrock_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: _t1 = (x - 1); -//CHECK-NEXT: _t0 = (x - 1); -//CHECK-NEXT: _t5 = x; -//CHECK-NEXT: _t4 = x; -//CHECK-NEXT: _t3 = (y - _t5 * _t4); -//CHECK-NEXT: _t6 = 100 * _t3; -//CHECK-NEXT: _t8 = x; -//CHECK-NEXT: _t7 = x; -//CHECK-NEXT: _t2 = (y - _t8 * _t7); //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * (x - 1); //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * 1; +//CHECK-NEXT: double _r1 = (x - 1) * 1; //CHECK-NEXT: * _d_x += _r1; -//CHECK-NEXT: double _r2 = 1 * _t2; -//CHECK-NEXT: double _r3 = _r2 * _t3; +//CHECK-NEXT: double _r2 = 1 * (y - x * x); +//CHECK-NEXT: double _r3 = _r2 * (y - x * x); //CHECK-NEXT: double _r4 = 100 * _r2; //CHECK-NEXT: * _d_y += _r4; -//CHECK-NEXT: double _r5 = -_r4 * _t4; +//CHECK-NEXT: double _r5 = -_r4 * x; //CHECK-NEXT: * _d_x += _r5; -//CHECK-NEXT: double _r6 = _t5 * -_r4; +//CHECK-NEXT: double _r6 = x * -_r4; //CHECK-NEXT: * _d_x += _r6; -//CHECK-NEXT: double _r7 = _t6 * 1; +//CHECK-NEXT: double _r7 = 100 * (y - x * x) * 1; //CHECK-NEXT: * _d_y += _r7; -//CHECK-NEXT: double _r8 = -_r7 * _t7; +//CHECK-NEXT: double _r8 = -_r7 * x; //CHECK-NEXT: * _d_x += _r8; -//CHECK-NEXT: double _r9 = _t8 * -_r7; +//CHECK-NEXT: double _r9 = x * -_r7; //CHECK-NEXT: * _d_x += _r9; //CHECK-NEXT: } //CHECK-NEXT: } @@ -361,6 +301,50 @@ double f_cond3(double x, double c) { double f_cond3_grad(double x, double c, clad::array_ref _d_x, clad::array_ref _d_y); +double f_cond4(double x, double y) { + int i = 0; + double arr[] = {x, y}; + if (x > 0) { + y = arr[i] * x; + } + return y; +} + +//CHECK: void f_cond4_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { +//CHECK-NEXT: int _d_i = 0; +//CHECK-NEXT: clad::array _d_arr(2UL); +//CHECK-NEXT: bool _cond0; +//CHECK-NEXT: double _t0; +//CHECK-NEXT: int i = 0; +//CHECK-NEXT: double arr[2] = {x, y}; +//CHECK-NEXT: _cond0 = x > 0; +//CHECK-NEXT: if (_cond0) { +//CHECK-NEXT: _t0 = y; +//CHECK-NEXT: y = arr[i] * x; +//CHECK-NEXT: } +//CHECK-NEXT: goto _label0; +//CHECK-NEXT: _label0: +//CHECK-NEXT: * _d_y += 1; +//CHECK-NEXT: if (_cond0) { +//CHECK-NEXT: { +//CHECK-NEXT: y = _t0; +//CHECK-NEXT: double _r_d0 = * _d_y; +//CHECK-NEXT: double _r0 = _r_d0 * x; +//CHECK-NEXT: _d_arr[i] += _r0; +//CHECK-NEXT: double _r1 = arr[i] * _r_d0; +//CHECK-NEXT: * _d_x += _r1; +//CHECK-NEXT: * _d_y -= _r_d0; +//CHECK-NEXT: * _d_y; +//CHECK-NEXT: } +//CHECK-NEXT: } +//CHECK-NEXT: { +//CHECK-NEXT: * _d_x += _d_arr[0]; +//CHECK-NEXT: * _d_y += _d_arr[1]; +//CHECK-NEXT: } +//CHECK-NEXT: } + +double f_cond4_grad(double x, double c, clad::array_ref _d_x, clad::array_ref _d_y); + double f_if1(double x, double y) { if (x > y) return x; @@ -428,24 +412,16 @@ struct S { } //CHECK: void f_grad(double x, double y, clad::array_ref _d_this, clad::array_ref _d_x, clad::array_ref _d_y) { - //CHECK-NEXT: double _t0; - //CHECK-NEXT: double _t1; - //CHECK-NEXT: double _t2; - //CHECK-NEXT: double _t3; - //CHECK-NEXT: _t1 = this->c1; - //CHECK-NEXT: _t0 = x; - //CHECK-NEXT: _t3 = this->c2; - //CHECK-NEXT: _t2 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { - //CHECK-NEXT: double _r0 = 1 * _t0; + //CHECK-NEXT: double _r0 = 1 * x; //CHECK-NEXT: (* _d_this).c1 += _r0; - //CHECK-NEXT: double _r1 = _t1 * 1; + //CHECK-NEXT: double _r1 = this->c1 * 1; //CHECK-NEXT: * _d_x += _r1; - //CHECK-NEXT: double _r2 = 1 * _t2; + //CHECK-NEXT: double _r2 = 1 * y; //CHECK-NEXT: (* _d_this).c2 += _r2; - //CHECK-NEXT: double _r3 = _t3 * 1; + //CHECK-NEXT: double _r3 = this->c2 * 1; //CHECK-NEXT: * _d_y += _r3; //CHECK-NEXT: } //CHECK-NEXT: } @@ -492,31 +468,19 @@ void f_norm_grad(double x, double* _d_d); //CHECK: void f_norm_grad(double x, double y, double z, double d, clad::array_ref _d_x, clad::array_ref _d_y, clad::array_ref _d_z, clad::array_ref _d_d) { //CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: _t2 = z; -//CHECK-NEXT: _t3 = d; -//CHECK-NEXT: _t4 = sum_of_powers(_t0, _t1, _t2, _t3); -//CHECK-NEXT: _t5 = d; -//CHECK-NEXT: _t6 = 1 / _t5; +//CHECK-NEXT: _t0 = d; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: double _grad4 = 0.; //CHECK-NEXT: double _grad5 = 0.; -//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(_t4, _t6, 1, &_grad4, &_grad5); +//CHECK-NEXT: clad::custom_derivatives::pow_pullback(sum_of_powers(x, y, z, d), 1 / _t0, 1, &_grad4, &_grad5); //CHECK-NEXT: double _r0 = _grad4; //CHECK-NEXT: double _grad0 = 0.; //CHECK-NEXT: double _grad1 = 0.; //CHECK-NEXT: double _grad2 = 0.; //CHECK-NEXT: double _grad3 = 0.; -//CHECK-NEXT: clad::custom_derivatives::sum_of_powers_pullback(_t0, _t1, _t2, _t3, _r0, &_grad0, &_grad1, &_grad2, &_grad3); +//CHECK-NEXT: clad::custom_derivatives::sum_of_powers_pullback(x, y, z, d, _r0, &_grad0, &_grad1, &_grad2, &_grad3); //CHECK-NEXT: double _r1 = _grad0; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: double _r2 = _grad1; @@ -526,8 +490,8 @@ void f_norm_grad(double x, //CHECK-NEXT: double _r4 = _grad3; //CHECK-NEXT: * _d_d += _r4; //CHECK-NEXT: double _r5 = _grad5; -//CHECK-NEXT: double _r6 = _r5 / _t5; -//CHECK-NEXT: double _r7 = _r5 * -1 / (_t5 * _t5); +//CHECK-NEXT: double _r6 = _r5 / _t0; +//CHECK-NEXT: double _r7 = _r5 * -1 / (_t0 * _t0); //CHECK-NEXT: * _d_d += _r7; //CHECK-NEXT: } //CHECK-NEXT: } @@ -538,23 +502,15 @@ double f_sin(double x, double y) { void f_sin_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y); //CHECK: void f_sin_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t2 = y; -//CHECK-NEXT: _t3 = (std::sin(_t1) + std::sin(_t2)); -//CHECK-NEXT: _t0 = (x + y); //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; -// CHECK-NEXT: double _r1 = _r0 * clad::custom_derivatives{{(::std)?}}::sin_pushforward(_t1, 1.).pushforward; +//CHECK-NEXT: double _r0 = 1 * (x + y); +//CHECK-NEXT: double _r1 = _r0 * clad::custom_derivatives::sin_pushforward(x, 1.).pushforward; //CHECK-NEXT: * _d_x += _r1; -// CHECK-NEXT: double _r2 = _r0 * clad::custom_derivatives{{(::std)?}}::sin_pushforward(_t2, 1.).pushforward; +//CHECK-NEXT: double _r2 = _r0 * clad::custom_derivatives::sin_pushforward(y, 1.).pushforward; //CHECK-NEXT: * _d_y += _r2; -//CHECK-NEXT: double _r3 = _t3 * 1; +//CHECK-NEXT: double _r3 = (std::sin(x) + std::sin(y)) * 1; //CHECK-NEXT: * _d_x += _r3; //CHECK-NEXT: * _d_y += _r3; //CHECK-NEXT: } @@ -589,22 +545,16 @@ double f_decls1(double x, double y) { void f_decls1_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y); //CHECK: void f_decls1_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; //CHECK-NEXT: double _d_a = 0; -//CHECK-NEXT: double _t1; //CHECK-NEXT: double _d_b = 0; //CHECK-NEXT: double _d_c = 0; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: double a = 3 * _t0; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: double b = 5 * _t1; +//CHECK-NEXT: double a = 3 * x; +//CHECK-NEXT: double b = 5 * y; //CHECK-NEXT: double c = a + b; -//CHECK-NEXT: _t2 = c; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = 1 * _t2; +//CHECK-NEXT: double _r4 = 1 * c; //CHECK-NEXT: double _r5 = 2 * 1; //CHECK-NEXT: _d_c += _r5; //CHECK-NEXT: } @@ -613,12 +563,12 @@ void f_decls1_grad(double x, double y, clad::array_ref _d_x, clad::array //CHECK-NEXT: _d_b += _d_c; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r2 = _d_b * _t1; +//CHECK-NEXT: double _r2 = _d_b * y; //CHECK-NEXT: double _r3 = 5 * _d_b; //CHECK-NEXT: * _d_y += _r3; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_a * _t0; +//CHECK-NEXT: double _r0 = _d_a * x; //CHECK-NEXT: double _r1 = 3 * _d_a; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: } @@ -633,51 +583,37 @@ double f_decls2(double x, double y) { void f_decls2_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y); //CHECK: void f_decls2_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; //CHECK-NEXT: double _d_a = 0; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; //CHECK-NEXT: double _d_b = 0; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; //CHECK-NEXT: double _d_c = 0; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: double a = _t1 * _t0; -//CHECK-NEXT: _t3 = x; -//CHECK-NEXT: _t2 = y; -//CHECK-NEXT: double b = _t3 * _t2; -//CHECK-NEXT: _t5 = y; -//CHECK-NEXT: _t4 = y; -//CHECK-NEXT: double c = _t5 * _t4; -//CHECK-NEXT: _t6 = b; +//CHECK-NEXT: double a = x * x; +//CHECK-NEXT: double b = x * y; +//CHECK-NEXT: double c = y * y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: _d_a += 1; -//CHECK-NEXT: double _r6 = 1 * _t6; +//CHECK-NEXT: double _r6 = 1 * b; //CHECK-NEXT: double _r7 = 2 * 1; //CHECK-NEXT: _d_b += _r7; //CHECK-NEXT: _d_c += 1; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = _d_c * _t4; +//CHECK-NEXT: double _r4 = _d_c * y; //CHECK-NEXT: * _d_y += _r4; -//CHECK-NEXT: double _r5 = _t5 * _d_c; +//CHECK-NEXT: double _r5 = y * _d_c; //CHECK-NEXT: * _d_y += _r5; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r2 = _d_b * _t2; +//CHECK-NEXT: double _r2 = _d_b * y; //CHECK-NEXT: * _d_x += _r2; -//CHECK-NEXT: double _r3 = _t3 * _d_b; +//CHECK-NEXT: double _r3 = x * _d_b; //CHECK-NEXT: * _d_y += _r3; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_a * _t0; +//CHECK-NEXT: double _r0 = _d_a * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d_a; +//CHECK-NEXT: double _r1 = x * _d_a; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: } //CHECK-NEXT: } @@ -695,65 +631,52 @@ double f_decls3(double x, double y) { void f_decls3_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y); //CHECK: void f_decls3_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; //CHECK-NEXT: double _d_a = 0; -//CHECK-NEXT: double _t1; //CHECK-NEXT: double _d_c = 0; //CHECK-NEXT: bool _cond0; -//CHECK-NEXT: double _t2; //CHECK-NEXT: bool _cond1; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; //CHECK-NEXT: double _d_b = 0; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: double a = 3 * _t0; -//CHECK-NEXT: _t1 = y; -//CHECK-NEXT: double c = 333 * _t1; +//CHECK-NEXT: double a = 3 * x; +//CHECK-NEXT: double c = 333 * y; //CHECK-NEXT: _cond0 = x > 1; -//CHECK-NEXT: if (_cond0) { -//CHECK-NEXT: _t2 = a; +//CHECK-NEXT: if (_cond0) //CHECK-NEXT: goto _label0; -//CHECK-NEXT: } else { +//CHECK-NEXT: else { //CHECK-NEXT: _cond1 = x < -1; -//CHECK-NEXT: if (_cond1) { -//CHECK-NEXT: _t3 = a; +//CHECK-NEXT: if (_cond1) //CHECK-NEXT: goto _label1; -//CHECK-NEXT: } //CHECK-NEXT: } -//CHECK-NEXT: _t5 = a; -//CHECK-NEXT: _t4 = a; -//CHECK-NEXT: double b = _t5 * _t4; +//CHECK-NEXT: double b = a * a; //CHECK-NEXT: goto _label2; //CHECK-NEXT: _label2: //CHECK-NEXT: _d_b += 1; //CHECK-NEXT: { -//CHECK-NEXT: double _r8 = _d_b * _t4; +//CHECK-NEXT: double _r8 = _d_b * a; //CHECK-NEXT: _d_a += _r8; -//CHECK-NEXT: double _r9 = _t5 * _d_b; +//CHECK-NEXT: double _r9 = a * _d_b; //CHECK-NEXT: _d_a += _r9; //CHECK-NEXT: } //CHECK-NEXT: if (_cond0) //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = 1 * _t2; +//CHECK-NEXT: double _r4 = 1 * a; //CHECK-NEXT: double _r5 = 2 * 1; //CHECK-NEXT: _d_a += _r5; //CHECK-NEXT: } //CHECK-NEXT: else if (_cond1) //CHECK-NEXT: _label1: //CHECK-NEXT: { -//CHECK-NEXT: double _r6 = 1 * _t3; +//CHECK-NEXT: double _r6 = 1 * a; //CHECK-NEXT: double _r7 = -2 * 1; //CHECK-NEXT: _d_a += _r7; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r2 = _d_c * _t1; +//CHECK-NEXT: double _r2 = _d_c * y; //CHECK-NEXT: double _r3 = 333 * _d_c; //CHECK-NEXT: * _d_y += _r3; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_a * _t0; +//CHECK-NEXT: double _r0 = _d_a * x; //CHECK-NEXT: double _r1 = 3 * _d_a; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: } @@ -767,53 +690,29 @@ double f_issue138(double x, double y) { void f_issue138_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y); //CHECK: void f_issue138_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { //CHECK-NEXT: double _d__t1 = 0; -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: double _t9; -//CHECK-NEXT: double _t11; -//CHECK-NEXT: double _t12; //CHECK-NEXT: double _t10 = 1; -//CHECK-NEXT: _t3 = x; -//CHECK-NEXT: _t2 = x; -//CHECK-NEXT: _t4 = _t3 * _t2; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t5 = _t4 * _t1; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t9 = y; -//CHECK-NEXT: _t8 = y; -//CHECK-NEXT: _t11 = _t9 * _t8; -//CHECK-NEXT: _t7 = y; -//CHECK-NEXT: _t12 = _t11 * _t7; -//CHECK-NEXT: _t6 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; -//CHECK-NEXT: double _r1 = _r0 * _t1; -//CHECK-NEXT: double _r2 = _r1 * _t2; +//CHECK-NEXT: double _r0 = 1 * x; +//CHECK-NEXT: double _r1 = _r0 * x; +//CHECK-NEXT: double _r2 = _r1 * x; //CHECK-NEXT: * _d_x += _r2; -//CHECK-NEXT: double _r3 = _t3 * _r1; +//CHECK-NEXT: double _r3 = x * _r1; //CHECK-NEXT: * _d_x += _r3; -//CHECK-NEXT: double _r4 = _t4 * _r0; +//CHECK-NEXT: double _r4 = x * x * _r0; //CHECK-NEXT: * _d_x += _r4; -//CHECK-NEXT: double _r5 = _t5 * 1; +//CHECK-NEXT: double _r5 = x * x * x * 1; //CHECK-NEXT: * _d_x += _r5; -//CHECK-NEXT: double _r6 = 1 * _t6; -//CHECK-NEXT: double _r7 = _r6 * _t7; -//CHECK-NEXT: double _r8 = _r7 * _t8; +//CHECK-NEXT: double _r6 = 1 * y; +//CHECK-NEXT: double _r7 = _r6 * y; +//CHECK-NEXT: double _r8 = _r7 * y; //CHECK-NEXT: * _d_y += _r8; -//CHECK-NEXT: double _r9 = _t9 * _r7; +//CHECK-NEXT: double _r9 = y * _r7; //CHECK-NEXT: * _d_y += _r9; -//CHECK-NEXT: double _r10 = _t11 * _r6; +//CHECK-NEXT: double _r10 = y * y * _r6; //CHECK-NEXT: * _d_y += _r10; -//CHECK-NEXT: double _r11 = _t12 * 1; +//CHECK-NEXT: double _r11 = y * y * y * 1; //CHECK-NEXT: * _d_y += _r11; //CHECK-NEXT: } //CHECK-NEXT: } @@ -823,17 +722,13 @@ double f_const(const double a, const double b) { } void f_const_grad(const double a, const double b, clad::array_ref _d_a, clad::array_ref _d_b); -//CHECK: void f_const_grad(const double a, const double b, clad::array_ref _d_a, clad::array_ref _d_b) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: _t1 = a; -//CHECK-NEXT: _t0 = b; +//CHECK: void f_const_grad(const double a, const double b, clad::array_ref _d_a, clad::array_ref _d_b) { //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * b; //CHECK-NEXT: * _d_a += _r0; -//CHECK-NEXT: double _r1 = _t1 * 1; +//CHECK-NEXT: double _r1 = a * 1; //CHECK-NEXT: * _d_b += _r1; //CHECK-NEXT: } //CHECK-NEXT: } @@ -848,18 +743,16 @@ void f_const_reference_grad(double i, double j, clad::array_ref _d_i, cl //CHECK: void f_const_reference_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { //CHECK-NEXT: double _d_a = 0; //CHECK-NEXT: double *_d_ar = 0; -//CHECK-NEXT: double _t0; //CHECK-NEXT: double _d_res = 0; //CHECK-NEXT: double a = i; //CHECK-NEXT: _d_ar = &_d_a; //CHECK-NEXT: const double &ar = a; -//CHECK-NEXT: _t0 = ar; -//CHECK-NEXT: double res = 2 * _t0; +//CHECK-NEXT: double res = 2 * ar; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_res += 1; //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_res * _t0; +//CHECK-NEXT: double _r0 = _d_res * ar; //CHECK-NEXT: double _r1 = 2 * _d_res; //CHECK-NEXT: *_d_ar += _r1; //CHECK-NEXT: } @@ -893,27 +786,25 @@ float running_sum(float* p, int n) { // CHECK: void running_sum_grad(float *p, int n, clad::array_ref _d_p, clad::array_ref _d_n) { // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: clad::tape _t3 = {}; -// CHECK-NEXT: int _t5; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: for (int i = 1; i < n; i++) { // CHECK-NEXT: _t0++; -// CHECK-NEXT: p[clad::push(_t1, i)] += p[clad::push(_t3, i - 1)]; +// CHECK-NEXT: clad::push(_t1, p[i]); +// CHECK-NEXT: p[i] += p[i - 1]; // CHECK-NEXT: } -// CHECK-NEXT: _t5 = n - 1; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: -// CHECK-NEXT: _d_p[_t5] += 1; +// CHECK-NEXT: _d_p[n - 1] += 1; // CHECK-NEXT: for (; _t0; _t0--) { +// CHECK-NEXT: i--; // CHECK-NEXT: { -// CHECK-NEXT: int _t2 = clad::pop(_t1); -// CHECK-NEXT: float _r_d0 = _d_p[_t2]; -// CHECK-NEXT: _d_p[_t2] += _r_d0; -// CHECK-NEXT: int _t4 = clad::pop(_t3); -// CHECK-NEXT: _d_p[_t4] += _r_d0; -// CHECK-NEXT: _d_p[_t2] -= _r_d0; -// CHECK-NEXT: _d_p[_t2]; +// CHECK-NEXT: p[i] = clad::pop(_t1); +// CHECK-NEXT: float _r_d0 = _d_p[i]; +// CHECK-NEXT: _d_p[i] += _r_d0; +// CHECK-NEXT: _d_p[i - 1] += _r_d0; +// CHECK-NEXT: _d_p[i] -= _r_d0; +// CHECK-NEXT: _d_p[i]; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: } @@ -927,17 +818,13 @@ double fn_global_var_use(double i, double j) { // CHECK: void fn_global_var_use_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { // CHECK-NEXT: double _d_ref = 0; -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; // CHECK-NEXT: double &ref = global; -// CHECK-NEXT: _t1 = ref; -// CHECK-NEXT: _t0 = i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; +// CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: _d_ref += _r0; -// CHECK-NEXT: double _r1 = _t1 * 1; +// CHECK-NEXT: double _r1 = ref * 1; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: } // CHECK-NEXT: } @@ -968,6 +855,7 @@ int main() { TEST(f_cond1, 3, 2); // CHECK-EXEC: Result is = {1.00, 0.00} TEST(f_cond2, 3, -1); // CHECK-EXEC: Result is = {1.00, 0.00} TEST(f_cond3, 3, -1); // CHECK-EXEC: Result is = {1.00, -1.00} + TEST(f_cond4, 3, -1); // CHECK-EXEC: Result is = {6.00, 0.00} TEST(f_if1, 3, 2); // CHECK-EXEC: Result is = {1.00, 0.00} TEST(f_if2, -5, -4); // CHECK-EXEC: Result is = {0.00, -1.00} clad::gradient(&S::f); diff --git a/test/Gradient/Loops.C b/test/Gradient/Loops.C index 0b4be619c..7eac9b1e4 100644 --- a/test/Gradient/Loops.C +++ b/test/Gradient/Loops.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oReverseLoops.out 2>&1 | FileCheck %s // RUN: ./ReverseLoops.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oReverseLoops.out +// RUN: ./ReverseLoops.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" @@ -19,21 +21,22 @@ double f1(double x) { //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: double t = 1; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < 3; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: clad::push(_t2, t); -//CHECK-NEXT: t *= clad::push(_t1, x); +//CHECK-NEXT: clad::push(_t1, t); +//CHECK-NEXT: t *= x; //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; +//CHECK-NEXT: t = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_t; -//CHECK-NEXT: _d_t += _r_d0 * clad::pop(_t1); -//CHECK-NEXT: double _r0 = clad::pop(_t2) * _r_d0; +//CHECK-NEXT: _d_t += _r_d0 * x; +//CHECK-NEXT: double _r0 = t * _r_d0; //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: _d_t -= _r_d0; //CHECK-NEXT: } @@ -52,32 +55,39 @@ double f2(double x) { //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: int _d_j = 0; -//CHECK-NEXT: clad::tape _t2 = {}; +//CHECK-NEXT: int j = 0; //CHECK-NEXT: clad::tape _t3 = {}; //CHECK-NEXT: double t = 1; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < 3; i++) { //CHECK-NEXT: _t0++; //CHECK-NEXT: clad::push(_t1, 0UL); -//CHECK-NEXT: for (int j = 0; j < 3; j++) { +//CHECK-NEXT: for (clad::push(_t2, j) , j = 0; j < 3; j++) { //CHECK-NEXT: clad::back(_t1)++; //CHECK-NEXT: clad::push(_t3, t); -//CHECK-NEXT: t *= clad::push(_t2, x); +//CHECK-NEXT: t *= x; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: for (; clad::back(_t1); clad::back(_t1)--) { +//CHECK-NEXT: j--; +//CHECK-NEXT: t = clad::pop(_t3); //CHECK-NEXT: double _r_d0 = _d_t; -//CHECK-NEXT: _d_t += _r_d0 * clad::pop(_t2); -//CHECK-NEXT: double _r0 = clad::pop(_t3) * _r_d0; +//CHECK-NEXT: _d_t += _r_d0 * x; +//CHECK-NEXT: double _r0 = t * _r_d0; //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: _d_t -= _r_d0; //CHECK-NEXT: } -//CHECK-NEXT: _d_j = 0; +//CHECK-NEXT: { +//CHECK-NEXT: _d_j = 0; +//CHECK-NEXT: j = clad::pop(_t2); +//CHECK-NEXT: } //CHECK-NEXT: clad::pop(_t1); //CHECK-NEXT: } //CHECK-NEXT: } @@ -97,32 +107,33 @@ double f3(double x) { //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t2 = {}; -//CHECK-NEXT: clad::tape _t4 = {}; +//CHECK-NEXT: clad::tape _t3 = {}; //CHECK-NEXT: double t = 1; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < 3; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: clad::push(_t2, t); -//CHECK-NEXT: t *= clad::push(_t1, x); -//CHECK-NEXT: bool _t3 = i == 1; +//CHECK-NEXT: clad::push(_t1, t); +//CHECK-NEXT: t *= x; +//CHECK-NEXT: bool _t2 = i == 1; //CHECK-NEXT: { -//CHECK-NEXT: if (_t3) +//CHECK-NEXT: if (_t2) //CHECK-NEXT: goto _label0; -//CHECK-NEXT: clad::push(_t4, _t3); +//CHECK-NEXT: clad::push(_t3, _t2); //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: goto _label1; //CHECK-NEXT: _label1: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: for (; _t0; _t0--) { -//CHECK-NEXT: if (clad::pop(_t4)) +//CHECK-NEXT: i--; +//CHECK-NEXT: if (clad::pop(_t3)) //CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: { +//CHECK-NEXT: t = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_t; -//CHECK-NEXT: _d_t += _r_d0 * clad::pop(_t1); -//CHECK-NEXT: double _r0 = clad::pop(_t2) * _r_d0; +//CHECK-NEXT: _d_t += _r_d0 * x; +//CHECK-NEXT: double _r0 = t * _r_d0; //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: _d_t -= _r_d0; //CHECK-NEXT: } @@ -141,10 +152,9 @@ double f4(double x) { //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; //CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: double t = 1; //CHECK-NEXT: _t0 = 0; -//CHECK-NEXT: for (int i = 0; i < 3; clad::push(_t2, t) , (t *= clad::push(_t1, x))) { +//CHECK-NEXT: for (int i = 0; i < 3; clad::push(_t1, t) , (t *= x)) { //CHECK-NEXT: _t0++; //CHECK-NEXT: i++; //CHECK-NEXT: } @@ -152,11 +162,15 @@ double f4(double x) { //CHECK-NEXT: _label0: //CHECK-NEXT: _d_t += 1; //CHECK-NEXT: for (; _t0; _t0--) { -//CHECK-NEXT: double _r_d0 = _d_t; -//CHECK-NEXT: _d_t += _r_d0 * clad::pop(_t1); -//CHECK-NEXT: double _r0 = clad::pop(_t2) * _r_d0; -//CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: _d_t -= _r_d0; +//CHECK-NEXT: { +//CHECK-NEXT: t = clad::pop(_t1); +//CHECK-NEXT: double _r_d0 = _d_t; +//CHECK-NEXT: _d_t += _r_d0 * x; +//CHECK-NEXT: double _r0 = t * _r_d0; +//CHECK-NEXT: * _d_x += _r0; +//CHECK-NEXT: _d_t -= _r_d0; +//CHECK-NEXT: } +//CHECK-NEXT: i--; //CHECK-NEXT: } //CHECK-NEXT: } @@ -177,8 +191,11 @@ double f5(double x){ //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: * _d_x += 1; -//CHECK-NEXT: for (; _t0; _t0--) -//CHECK-NEXT: ; +//CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; +//CHECK-NEXT: x--; +//CHECK-NEXT: * _d_x; +//CHECK-NEXT: } //CHECK-NEXT: } double f_sum(double *p, int n) { @@ -193,37 +210,35 @@ double f_sum(double *p, int n) { //CHECK-NEXT: double _d_s = 0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: double s = 0; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < n; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: s += p[clad::push(_t1, i)]; +//CHECK-NEXT: clad::push(_t1, s); +//CHECK-NEXT: s += p[i]; //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_s += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; +//CHECK-NEXT: s = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_s; //CHECK-NEXT: _d_s += _r_d0; -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: _d_p[_t2] += _r_d0; +//CHECK-NEXT: _d_p[i] += _r_d0; //CHECK-NEXT: _d_s -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: } double sq(double x) { return x * x; } //CHECK: void sq_pullback(double x, double _d_y, clad::array_ref _d_x) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_y * _t0; +//CHECK-NEXT: double _r0 = _d_y * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d_y; +//CHECK-NEXT: double _r1 = x * _d_y; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: } //CHECK-NEXT: } @@ -240,25 +255,26 @@ double f_sum_squares(double *p, int n) { //CHECK-NEXT: double _d_s = 0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t3 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: double s = 0; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < n; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: s += sq(clad::push(_t3, p[clad::push(_t1, i)])); +//CHECK-NEXT: clad::push(_t1, s); +//CHECK-NEXT: s += sq(p[i]); //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_s += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; +//CHECK-NEXT: s = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_s; //CHECK-NEXT: _d_s += _r_d0; //CHECK-NEXT: double _grad0 = 0.; -//CHECK-NEXT: sq_pullback(clad::pop(_t3), _r_d0, &_grad0); +//CHECK-NEXT: sq_pullback(p[i], _r_d0, &_grad0); //CHECK-NEXT: double _r0 = _grad0; -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: _d_p[_t2] += _r0; +//CHECK-NEXT: _d_p[i] += _r0; //CHECK-NEXT: _d_s -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: } @@ -272,100 +288,81 @@ double f_log_gaus(double* x, double* p /*means*/, double n, double sigma) { double gaus = 1./std::sqrt(std::pow(2*M_PI, n) * sigma) * std::exp(power); return std::log(gaus); } - -//CHECK: void f_log_gaus_grad_1(double *x, double *p, double n, double sigma, clad::array_ref _d_p) { +//CHECK-NEXT: void f_log_gaus_grad_1(double *x, double *p, double n, double sigma, clad::array_ref _d_p) { //CHECK-NEXT: double _d_n = 0; //CHECK-NEXT: double _d_sigma = 0; //CHECK-NEXT: double _d_power = 0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t3 = {}; -//CHECK-NEXT: clad::tape _t5 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; +//CHECK-NEXT: double _t2; +//CHECK-NEXT: double _t3; +//CHECK-NEXT: double _t4; +//CHECK-NEXT: double _t5; //CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: double _t9; -//CHECK-NEXT: double _t10; -//CHECK-NEXT: double _t11; -//CHECK-NEXT: double _t12; -//CHECK-NEXT: double _t13; -//CHECK-NEXT: double _t14; -//CHECK-NEXT: double _t15; -//CHECK-NEXT: double _t16; -//CHECK-NEXT: double _t17; -//CHECK-NEXT: double _t18; //CHECK-NEXT: double _d_gaus = 0; -//CHECK-NEXT: double _t19; //CHECK-NEXT: double power = 0; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < n; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: power += sq(clad::push(_t5, x[clad::push(_t1, i)] - p[clad::push(_t3, i)])); +//CHECK-NEXT: clad::push(_t1, power); +//CHECK-NEXT: power += sq(x[i] - p[i]); //CHECK-NEXT: } -//CHECK-NEXT: _t7 = -power; -//CHECK-NEXT: _t9 = sigma; -//CHECK-NEXT: _t8 = sq(_t9); -//CHECK-NEXT: _t6 = (2 * _t8); -//CHECK-NEXT: power = _t7 / _t6; -//CHECK-NEXT: _t13 = 2 * 3.1415926535897931; -//CHECK-NEXT: _t14 = n; -//CHECK-NEXT: _t15 = std::pow(_t13, _t14); -//CHECK-NEXT: _t12 = sigma; -//CHECK-NEXT: _t16 = _t15 * _t12; -//CHECK-NEXT: _t11 = std::sqrt(_t16); -//CHECK-NEXT: _t17 = 1. / _t11; -//CHECK-NEXT: _t18 = power; -//CHECK-NEXT: _t10 = std::exp(_t18); -//CHECK-NEXT: double gaus = _t17 * _t10; -//CHECK-NEXT: _t19 = gaus; +//CHECK-NEXT: _t2 = power; +//CHECK-NEXT: _t4 = sq(sigma); +//CHECK-NEXT: _t3 = (2 * _t4); +//CHECK-NEXT: power = -power / _t3; +//CHECK-NEXT: _t6 = std::sqrt(std::pow(2 * 3.1415926535897931, n) * sigma); +//CHECK-NEXT: _t5 = std::exp(power); +//CHECK-NEXT: double gaus = 1. / _t6 * _t5; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r17 = 1 * clad::custom_derivatives::log_pushforward(_t19, 1.).pushforward; +//CHECK-NEXT: double _r17 = 1 * clad::custom_derivatives::log_pushforward(gaus, 1.).pushforward; //CHECK-NEXT: _d_gaus += _r17; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r6 = _d_gaus * _t10; -//CHECK-NEXT: double _r7 = _r6 / _t11; -//CHECK-NEXT: double _r8 = _r6 * -1. / (_t11 * _t11); -//CHECK-NEXT: double _r9 = _r8 * clad::custom_derivatives::sqrt_pushforward(_t16, 1.).pushforward; -//CHECK-NEXT: double _r10 = _r9 * _t12; +//CHECK-NEXT: double _r6 = _d_gaus * _t5; +//CHECK-NEXT: double _r7 = _r6 / _t6; +//CHECK-NEXT: double _r8 = _r6 * -1. / (_t6 * _t6); +//CHECK-NEXT: double _r9 = _r8 * clad::custom_derivatives::sqrt_pushforward(std::pow(2 * 3.1415926535897931, n) * sigma, 1.).pushforward; +//CHECK-NEXT: double _r10 = _r9 * sigma; //CHECK-NEXT: double _grad2 = 0.; //CHECK-NEXT: double _grad3 = 0.; -//CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(_t13, _t14, _r10, &_grad2, &_grad3); +//CHECK-NEXT: clad::custom_derivatives::pow_pullback(2 * 3.1415926535897931, n, _r10, &_grad2, &_grad3); //CHECK-NEXT: double _r11 = _grad2; //CHECK-NEXT: double _r12 = _r11 * 3.1415926535897931; //CHECK-NEXT: double _r13 = _grad3; //CHECK-NEXT: _d_n += _r13; -//CHECK-NEXT: double _r14 = _t15 * _r9; +//CHECK-NEXT: double _r14 = std::pow(2 * 3.1415926535897931, n) * _r9; //CHECK-NEXT: _d_sigma += _r14; -//CHECK-NEXT: double _r15 = _t17 * _d_gaus; -//CHECK-NEXT: double _r16 = _r15 * clad::custom_derivatives::exp_pushforward(_t18, 1.).pushforward; +//CHECK-NEXT: double _r15 = 1. / _t6 * _d_gaus; +//CHECK-NEXT: double _r16 = _r15 * clad::custom_derivatives::exp_pushforward(power, 1.).pushforward; //CHECK-NEXT: _d_power += _r16; //CHECK-NEXT: } //CHECK-NEXT: { +//CHECK-NEXT: power = _t2; //CHECK-NEXT: double _r_d1 = _d_power; -//CHECK-NEXT: double _r1 = _r_d1 / _t6; +//CHECK-NEXT: double _r1 = _r_d1 / _t3; //CHECK-NEXT: _d_power += -_r1; -//CHECK-NEXT: double _r2 = _r_d1 * -_t7 / (_t6 * _t6); -//CHECK-NEXT: double _r3 = _r2 * _t8; +//CHECK-NEXT: double _r2 = _r_d1 * --power / (_t3 * _t3); +//CHECK-NEXT: double _r3 = _r2 * _t4; //CHECK-NEXT: double _r4 = 2 * _r2; //CHECK-NEXT: double _grad1 = 0.; -//CHECK-NEXT: sq_pullback(_t9, _r4, &_grad1); +//CHECK-NEXT: sq_pullback(sigma, _r4, &_grad1); //CHECK-NEXT: double _r5 = _grad1; //CHECK-NEXT: _d_sigma += _r5; //CHECK-NEXT: _d_power -= _r_d1; //CHECK-NEXT: } //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; +//CHECK-NEXT: power = clad::pop(_t1); //CHECK-NEXT: double _r_d0 = _d_power; //CHECK-NEXT: _d_power += _r_d0; //CHECK-NEXT: double _grad0 = 0.; -//CHECK-NEXT: sq_pullback(clad::pop(_t5), _r_d0, &_grad0); +//CHECK-NEXT: sq_pullback(x[i] - p[i], _r_d0, &_grad0); //CHECK-NEXT: double _r0 = _grad0; -//CHECK-NEXT: int _t2 = clad::pop(_t1); -//CHECK-NEXT: int _t4 = clad::pop(_t3); -//CHECK-NEXT: _d_p[_t4] += -_r0; +//CHECK-NEXT: _d_p[i] += -_r0; //CHECK-NEXT: _d_power -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: } @@ -384,32 +381,37 @@ void f_const_grad(const double, const double, clad::array_ref, clad::arr //CHECK-NEXT: int _d_r = 0; //CHECK-NEXT: unsigned long _t0; //CHECK-NEXT: int _d_i = 0; -//CHECK-NEXT: clad::tape _t1 = {}; -//CHECK-NEXT: clad::tape _t2 = {}; +//CHECK-NEXT: clad::tape _t1 = {}; //CHECK-NEXT: int _d_sq = 0; +//CHECK-NEXT: int sq0 = 0; +//CHECK-NEXT: clad::tape _t2 = {}; //CHECK-NEXT: int r = 0; //CHECK-NEXT: _t0 = 0; //CHECK-NEXT: for (int i = 0; i < a; i++) { //CHECK-NEXT: _t0++; -//CHECK-NEXT: int sq0 = clad::push(_t2, b) * clad::push(_t1, b); +//CHECK-NEXT: clad::push(_t1, sq0) , sq0 = b * b; +//CHECK-NEXT: clad::push(_t2, r); //CHECK-NEXT: r += sq0; //CHECK-NEXT: } //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_r += 1; //CHECK-NEXT: for (; _t0; _t0--) { +//CHECK-NEXT: i--; //CHECK-NEXT: { +//CHECK-NEXT: r = clad::pop(_t2); //CHECK-NEXT: int _r_d0 = _d_r; //CHECK-NEXT: _d_r += _r_d0; //CHECK-NEXT: _d_sq += _r_d0; //CHECK-NEXT: _d_r -= _r_d0; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_sq * clad::pop(_t1); +//CHECK-NEXT: double _r0 = _d_sq * b; //CHECK-NEXT: * _d_b += _r0; -//CHECK-NEXT: double _r1 = clad::pop(_t2) * _d_sq; +//CHECK-NEXT: double _r1 = b * _d_sq; //CHECK-NEXT: * _d_b += _r1; -// CHECK-NEXT: _d_sq = 0; +//CHECK-NEXT: _d_sq = 0; +//CHECK-NEXT: sq0 = clad::pop(_t1); //CHECK-NEXT: } //CHECK-NEXT: } //CHECK-NEXT: } @@ -430,25 +432,31 @@ double f6 (double i, double j) { // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_counter = 0; // CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: clad::tape _t2 = {}; // CHECK-NEXT: double _d_b = 0; +// CHECK-NEXT: double b = 0; +// CHECK-NEXT: clad::tape _t2 = {}; +// CHECK-NEXT: double _d_c = 0; +// CHECK-NEXT: double c = 0; // CHECK-NEXT: clad::tape _t3 = {}; // CHECK-NEXT: clad::tape _t4 = {}; -// CHECK-NEXT: double _d_c = 0; // CHECK-NEXT: double a = 0; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: for (int counter = 0; counter < 3; ++counter) { // CHECK-NEXT: _t0++; -// CHECK-NEXT: double b = clad::push(_t2, i) * clad::push(_t1, i); -// CHECK-NEXT: double c = clad::push(_t4, j) * clad::push(_t3, j); +// CHECK-NEXT: clad::push(_t1, b) , b = i * i; +// CHECK-NEXT: clad::push(_t2, c) , c = j * j; +// CHECK-NEXT: clad::push(_t3, b); // CHECK-NEXT: b += j; +// CHECK-NEXT: clad::push(_t4, a); // CHECK-NEXT: a += b + c + i; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_a += 1; // CHECK-NEXT: for (; _t0; _t0--) { +// CHECK-NEXT: --counter; // CHECK-NEXT: { +// CHECK-NEXT: a = clad::pop(_t4); // CHECK-NEXT: double _r_d1 = _d_a; // CHECK-NEXT: _d_a += _r_d1; // CHECK-NEXT: _d_b += _r_d1; @@ -457,24 +465,27 @@ double f6 (double i, double j) { // CHECK-NEXT: _d_a -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: b = clad::pop(_t3); // CHECK-NEXT: double _r_d0 = _d_b; // CHECK-NEXT: _d_b += _r_d0; // CHECK-NEXT: * _d_j += _r_d0; // CHECK-NEXT: _d_b -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: double _r2 = _d_c * clad::pop(_t3); +// CHECK-NEXT: double _r2 = _d_c * j; // CHECK-NEXT: * _d_j += _r2; -// CHECK-NEXT: double _r3 = clad::pop(_t4) * _d_c; +// CHECK-NEXT: double _r3 = j * _d_c; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: _d_c = 0; +// CHECK-NEXT: c = clad::pop(_t2); // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = _d_b * clad::pop(_t1); +// CHECK-NEXT: double _r0 = _d_b * i; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = clad::pop(_t2) * _d_b; +// CHECK-NEXT: double _r1 = i * _d_b; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: _d_b = 0; +// CHECK-NEXT: b = clad::pop(_t1); // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: } @@ -492,14 +503,14 @@ double fn7(double i, double j) { // CHECK-NEXT: int _d_counter = 0; // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: clad::tape _t2 = {}; // CHECK-NEXT: double a = 0; // CHECK-NEXT: int counter = 3; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: while (counter--) // CHECK-NEXT: { // CHECK-NEXT: _t0++; -// CHECK-NEXT: a += clad::push(_t2, i) * clad::push(_t1, i) + j; +// CHECK-NEXT: clad::push(_t1, a); +// CHECK-NEXT: a += i * i + j; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: @@ -507,11 +518,12 @@ double fn7(double i, double j) { // CHECK-NEXT: while (_t0) // CHECK-NEXT: { // CHECK-NEXT: { +// CHECK-NEXT: a = clad::pop(_t1); // CHECK-NEXT: double _r_d0 = _d_a; // CHECK-NEXT: _d_a += _r_d0; -// CHECK-NEXT: double _r0 = _r_d0 * clad::pop(_t1); +// CHECK-NEXT: double _r0 = _r_d0 * i; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = clad::pop(_t2) * _r_d0; +// CHECK-NEXT: double _r1 = i * _r_d0; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: * _d_j += _r_d0; // CHECK-NEXT: _d_a -= _r_d0; @@ -536,7 +548,6 @@ double fn8(double i, double j) { // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: clad::tape _t2 = {}; -// CHECK-NEXT: clad::tape _t3 = {}; // CHECK-NEXT: double a = 0; // CHECK-NEXT: int counter = 3; // CHECK-NEXT: _t0 = 0; @@ -546,7 +557,8 @@ double fn8(double i, double j) { // CHECK-NEXT: clad::push(_t1, 0UL); // CHECK-NEXT: do { // CHECK-NEXT: clad::back(_t1)++; -// CHECK-NEXT: a += clad::push(_t3, i) * clad::push(_t2, i) + j; +// CHECK-NEXT: clad::push(_t2, a); +// CHECK-NEXT: a += i * i + j; // CHECK-NEXT: } while (--counter); // CHECK-NEXT: } // CHECK-NEXT: goto _label0; @@ -558,11 +570,12 @@ double fn8(double i, double j) { // CHECK-NEXT: do { // CHECK-NEXT: { // CHECK-NEXT: { +// CHECK-NEXT: a = clad::pop(_t2); // CHECK-NEXT: double _r_d0 = _d_a; // CHECK-NEXT: _d_a += _r_d0; -// CHECK-NEXT: double _r0 = _r_d0 * clad::pop(_t2); +// CHECK-NEXT: double _r0 = _r_d0 * i; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = clad::pop(_t3) * _r_d0; +// CHECK-NEXT: double _r1 = i * _r_d0; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: * _d_j += _r_d0; // CHECK-NEXT: _d_a -= _r_d0; @@ -591,61 +604,71 @@ double fn9(double i, double j) { // CHECK: void fn9_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { // CHECK-NEXT: int _d_counter = 0, _d_counter_again = 0; +// CHECK-NEXT: int _t0; +// CHECK-NEXT: int _t1; // CHECK-NEXT: double _d_a = 0; -// CHECK-NEXT: unsigned long _t0; -// CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: clad::tape _t2 = {}; -// CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: unsigned long _t2; +// CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: clad::tape _t4 = {}; +// CHECK-NEXT: clad::tape _t5 = {}; // CHECK-NEXT: int counter, counter_again; +// CHECK-NEXT: _t0 = counter; +// CHECK-NEXT: _t1 = counter_again; // CHECK-NEXT: counter = counter_again = 3; // CHECK-NEXT: double a = 0; -// CHECK-NEXT: _t0 = 0; +// CHECK-NEXT: _t2 = 0; // CHECK-NEXT: while (counter--) // CHECK-NEXT: { -// CHECK-NEXT: _t0++; +// CHECK-NEXT: _t2++; +// CHECK-NEXT: clad::push(_t3, counter_again); // CHECK-NEXT: counter_again = 3; -// CHECK-NEXT: clad::push(_t1, 0UL); +// CHECK-NEXT: clad::push(_t4, 0UL); // CHECK-NEXT: while (counter_again--) // CHECK-NEXT: { -// CHECK-NEXT: clad::back(_t1)++; -// CHECK-NEXT: a += clad::push(_t3, i) * clad::push(_t2, i) + j; +// CHECK-NEXT: clad::back(_t4)++; +// CHECK-NEXT: clad::push(_t5, a); +// CHECK-NEXT: a += i * i + j; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_a += 1; -// CHECK-NEXT: while (_t0) +// CHECK-NEXT: while (_t2) // CHECK-NEXT: { // CHECK-NEXT: { // CHECK-NEXT: { -// CHECK-NEXT: while (clad::back(_t1)) +// CHECK-NEXT: while (clad::back(_t4)) // CHECK-NEXT: { // CHECK-NEXT: { // CHECK-NEXT: { +// CHECK-NEXT: a = clad::pop(_t5); // CHECK-NEXT: double _r_d3 = _d_a; // CHECK-NEXT: _d_a += _r_d3; -// CHECK-NEXT: double _r0 = _r_d3 * clad::pop(_t2); +// CHECK-NEXT: double _r0 = _r_d3 * i; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = clad::pop(_t3) * _r_d3; +// CHECK-NEXT: double _r1 = i * _r_d3; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: * _d_j += _r_d3; // CHECK-NEXT: _d_a -= _r_d3; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: clad::back(_t1)--; +// CHECK-NEXT: clad::back(_t4)--; // CHECK-NEXT: } -// CHECK-NEXT: clad::pop(_t1); +// CHECK-NEXT: clad::pop(_t4); // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: counter_again = clad::pop(_t3); // CHECK-NEXT: int _r_d2 = _d_counter_again; // CHECK-NEXT: _d_counter_again -= _r_d2; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: _t0--; +// CHECK-NEXT: _t2--; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: counter = _t0; // CHECK-NEXT: int _r_d0 = _d_counter; // CHECK-NEXT: _d_counter_again += _r_d0; +// CHECK-NEXT: counter_again = _t1; // CHECK-NEXT: int _r_d1 = _d_counter_again; // CHECK-NEXT: _d_counter_again -= _r_d1; // CHECK-NEXT: _d_counter -= _r_d0; @@ -667,17 +690,23 @@ double fn10(double i, double j) { // CHECK-NEXT: double _d_a = 0; // CHECK-NEXT: int _d_counter = 0; // CHECK-NEXT: unsigned long _t0; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: int _d_b = 0; -// CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: clad::tape _t2 = {}; +// CHECK-NEXT: int b = 0; +// CHECK-NEXT: clad::tape _t2 = {}; +// CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: clad::tape _t4 = {}; // CHECK-NEXT: double a = 0; // CHECK-NEXT: int counter = 3; // CHECK-NEXT: _t0 = 0; -// CHECK-NEXT: while (int b = counter) +// CHECK-NEXT: while (clad::push(_t1, b) , b = counter) // CHECK-NEXT: { // CHECK-NEXT: _t0++; -// CHECK-NEXT: b += clad::push(_t2, i) * clad::push(_t1, i) + j; +// CHECK-NEXT: clad::push(_t2, b); +// CHECK-NEXT: b += i * i + j; +// CHECK-NEXT: clad::push(_t3, a); // CHECK-NEXT: a += b; +// CHECK-NEXT: clad::push(_t4, counter); // CHECK-NEXT: counter -= 1; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; @@ -687,22 +716,25 @@ double fn10(double i, double j) { // CHECK-NEXT: { // CHECK-NEXT: { // CHECK-NEXT: { +// CHECK-NEXT: counter = clad::pop(_t4); // CHECK-NEXT: int _r_d2 = _d_counter; // CHECK-NEXT: _d_counter += _r_d2; // CHECK-NEXT: _d_counter -= _r_d2; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: a = clad::pop(_t3); // CHECK-NEXT: double _r_d1 = _d_a; // CHECK-NEXT: _d_a += _r_d1; // CHECK-NEXT: _d_b += _r_d1; // CHECK-NEXT: _d_a -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: b = clad::pop(_t2); // CHECK-NEXT: int _r_d0 = _d_b; // CHECK-NEXT: _d_b += _r_d0; -// CHECK-NEXT: double _r0 = _r_d0 * clad::pop(_t1); +// CHECK-NEXT: double _r0 = _r_d0 * i; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = clad::pop(_t2) * _r_d0; +// CHECK-NEXT: double _r1 = i * _r_d0; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: * _d_j += _r_d0; // CHECK-NEXT: _d_b -= _r_d0; @@ -711,6 +743,7 @@ double fn10(double i, double j) { // CHECK-NEXT: { // CHECK-NEXT: _d_counter += _d_b; // CHECK-NEXT: _d_b = 0; +// CHECK-NEXT: b = clad::pop(_t1); // CHECK-NEXT: } // CHECK-NEXT: _t0--; // CHECK-NEXT: } @@ -731,13 +764,15 @@ double fn11(double i, double j) { // CHECK-NEXT: double _d_a = 0; // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: clad::tape _t2 = {}; +// CHECK-NEXT: clad::tape _t2 = {}; // CHECK-NEXT: int counter = 3; // CHECK-NEXT: double a = 0; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: do { // CHECK-NEXT: _t0++; -// CHECK-NEXT: a += clad::push(_t2, i) * clad::push(_t1, i) + j; +// CHECK-NEXT: clad::push(_t1, a); +// CHECK-NEXT: a += i * i + j; +// CHECK-NEXT: clad::push(_t2, counter); // CHECK-NEXT: counter -= 1; // CHECK-NEXT: } while (counter); // CHECK-NEXT: goto _label0; @@ -746,16 +781,18 @@ double fn11(double i, double j) { // CHECK-NEXT: do { // CHECK-NEXT: { // CHECK-NEXT: { +// CHECK-NEXT: counter = clad::pop(_t2); // CHECK-NEXT: int _r_d1 = _d_counter; // CHECK-NEXT: _d_counter += _r_d1; // CHECK-NEXT: _d_counter -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: a = clad::pop(_t1); // CHECK-NEXT: double _r_d0 = _d_a; // CHECK-NEXT: _d_a += _r_d0; -// CHECK-NEXT: double _r0 = _r_d0 * clad::pop(_t1); +// CHECK-NEXT: double _r0 = _r_d0 * i; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = clad::pop(_t2) * _r_d0; +// CHECK-NEXT: double _r1 = i * _r_d0; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: * _d_j += _r_d0; // CHECK-NEXT: _d_a -= _r_d0; @@ -786,28 +823,36 @@ double fn12(double i, double j) { // CHECK-NEXT: int _d_counter = 0; // CHECK-NEXT: double _d_a = 0; // CHECK-NEXT: unsigned long _t0; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: int _d_counter_again = 0; -// CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: clad::tape _t2 = {}; +// CHECK-NEXT: int counter_again = 0; +// CHECK-NEXT: clad::tape _t2 = {}; // CHECK-NEXT: clad::tape _t3 = {}; -// CHECK-NEXT: clad::tape _t4 = {}; +// CHECK-NEXT: clad::tape _t4 = {}; +// CHECK-NEXT: clad::tape _t5 = {}; +// CHECK-NEXT: clad::tape _t6 = {}; +// CHECK-NEXT: clad::tape _t7 = {}; // CHECK-NEXT: int counter = 3; // CHECK-NEXT: double a = 0; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: do { // CHECK-NEXT: _t0++; -// CHECK-NEXT: int counter_again = 3; -// CHECK-NEXT: clad::push(_t1, 0UL); +// CHECK-NEXT: clad::push(_t1, counter_again) , counter_again = 3; +// CHECK-NEXT: clad::push(_t2, 0UL); // CHECK-NEXT: do { -// CHECK-NEXT: clad::back(_t1)++; -// CHECK-NEXT: a += clad::push(_t3, i) * clad::push(_t2, i) + j; +// CHECK-NEXT: clad::back(_t2)++; +// CHECK-NEXT: clad::push(_t3, a); +// CHECK-NEXT: a += i * i + j; +// CHECK-NEXT: clad::push(_t4, counter_again); // CHECK-NEXT: counter_again -= 1; -// CHECK-NEXT: clad::push(_t4, 0UL); +// CHECK-NEXT: clad::push(_t5, 0UL); // CHECK-NEXT: do { -// CHECK-NEXT: clad::back(_t4)++; +// CHECK-NEXT: clad::back(_t5)++; +// CHECK-NEXT: clad::push(_t6, a); // CHECK-NEXT: a += j; // CHECK-NEXT: } while (0); // CHECK-NEXT: } while (counter_again); +// CHECK-NEXT: clad::push(_t7, counter); // CHECK-NEXT: counter -= 1; // CHECK-NEXT: } while (counter); // CHECK-NEXT: goto _label0; @@ -816,6 +861,7 @@ double fn12(double i, double j) { // CHECK-NEXT: do { // CHECK-NEXT: { // CHECK-NEXT: { +// CHECK-NEXT: counter = clad::pop(_t7); // CHECK-NEXT: int _r_d3 = _d_counter; // CHECK-NEXT: _d_counter += _r_d3; // CHECK-NEXT: _d_counter -= _r_d3; @@ -826,36 +872,42 @@ double fn12(double i, double j) { // CHECK-NEXT: { // CHECK-NEXT: do { // CHECK-NEXT: { +// CHECK-NEXT: a = clad::pop(_t6); // CHECK-NEXT: double _r_d2 = _d_a; // CHECK-NEXT: _d_a += _r_d2; // CHECK-NEXT: * _d_j += _r_d2; // CHECK-NEXT: _d_a -= _r_d2; // CHECK-NEXT: } -// CHECK-NEXT: clad::back(_t4)--; -// CHECK-NEXT: } while (clad::back(_t4)); -// CHECK-NEXT: clad::pop(_t4); +// CHECK-NEXT: clad::back(_t5)--; +// CHECK-NEXT: } while (clad::back(_t5)); +// CHECK-NEXT: clad::pop(_t5); // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: counter_again = clad::pop(_t4); // CHECK-NEXT: int _r_d1 = _d_counter_again; // CHECK-NEXT: _d_counter_again += _r_d1; // CHECK-NEXT: _d_counter_again -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: a = clad::pop(_t3); // CHECK-NEXT: double _r_d0 = _d_a; // CHECK-NEXT: _d_a += _r_d0; -// CHECK-NEXT: double _r0 = _r_d0 * clad::pop(_t2); +// CHECK-NEXT: double _r0 = _r_d0 * i; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = clad::pop(_t3) * _r_d0; +// CHECK-NEXT: double _r1 = i * _r_d0; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: * _d_j += _r_d0; // CHECK-NEXT: _d_a -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: clad::back(_t1)--; -// CHECK-NEXT: } while (clad::back(_t1)); -// CHECK-NEXT: clad::pop(_t1); +// CHECK-NEXT: clad::back(_t2)--; +// CHECK-NEXT: } while (clad::back(_t2)); +// CHECK-NEXT: clad::pop(_t2); +// CHECK-NEXT: } +// CHECK-NEXT: { +// CHECK-NEXT: _d_counter_again = 0; +// CHECK-NEXT: counter_again = clad::pop(_t1); // CHECK-NEXT: } -// CHECK-NEXT: _d_counter_again = 0; // CHECK-NEXT: } // CHECK-NEXT: _t0--; // CHECK-NEXT: } while (_t0); @@ -876,16 +928,24 @@ double fn13(double i, double j) { // CHECK-NEXT: double _d_res = 0; // CHECK-NEXT: int _d_counter = 0; // CHECK-NEXT: unsigned long _t0; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: int _d_k = 0; -// CHECK-NEXT: clad::tape _t1 = {}; +// CHECK-NEXT: int k = 0; +// CHECK-NEXT: clad::tape _t2 = {}; +// CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: clad::tape _t4 = {}; // CHECK-NEXT: double _d_temp = 0; +// CHECK-NEXT: double temp = 0; +// CHECK-NEXT: clad::tape _t5 = {}; // CHECK-NEXT: double res = 0; // CHECK-NEXT: int counter = 3; // CHECK-NEXT: _t0 = 0; -// CHECK-NEXT: for (; k; counter -= 1) { +// CHECK-NEXT: for (; clad::push(_t1, k) , k = counter; clad::push(_t2, counter) , (counter -= 1)) { // CHECK-NEXT: _t0++; -// CHECK-NEXT: k += i + 2 * clad::push(_t1, j); -// CHECK-NEXT: double temp = k; +// CHECK-NEXT: clad::push(_t3, k); +// CHECK-NEXT: k += i + 2 * j; +// CHECK-NEXT: clad::push(_t4, temp) , temp = k; +// CHECK-NEXT: clad::push(_t5, res); // CHECK-NEXT: res += temp; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; @@ -893,12 +953,14 @@ double fn13(double i, double j) { // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: for (; _t0; _t0--) { // CHECK-NEXT: { -// CHECK-NEXT: int _r_d0 = _d_counter; -// CHECK-NEXT: _d_counter += _r_d0; -// CHECK-NEXT: _d_counter -= _r_d0; -// CHECK-NEXT: } -// CHECK-NEXT: { // CHECK-NEXT: { +// CHECK-NEXT: counter = clad::pop(_t2); +// CHECK-NEXT: int _r_d0 = _d_counter; +// CHECK-NEXT: _d_counter += _r_d0; +// CHECK-NEXT: _d_counter -= _r_d0; +// CHECK-NEXT: } +// CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t5); // CHECK-NEXT: double _r_d2 = _d_res; // CHECK-NEXT: _d_res += _r_d2; // CHECK-NEXT: _d_temp += _r_d2; @@ -907,12 +969,14 @@ double fn13(double i, double j) { // CHECK-NEXT: { // CHECK-NEXT: _d_k += _d_temp; // CHECK-NEXT: _d_temp = 0; +// CHECK-NEXT: temp = clad::pop(_t4); // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: k = clad::pop(_t3); // CHECK-NEXT: int _r_d1 = _d_k; // CHECK-NEXT: _d_k += _r_d1; // CHECK-NEXT: * _d_i += _r_d1; -// CHECK-NEXT: double _r0 = _r_d1 * clad::pop(_t1); +// CHECK-NEXT: double _r0 = _r_d1 * j; // CHECK-NEXT: int _r1 = 2 * _r_d1; // CHECK-NEXT: * _d_j += _r1; // CHECK-NEXT: _d_k -= _r_d1; @@ -921,6 +985,7 @@ double fn13(double i, double j) { // CHECK-NEXT: { // CHECK-NEXT: _d_counter += _d_k; // CHECK-NEXT: _d_k = 0; +// CHECK-NEXT: k = clad::pop(_t1); // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: } @@ -951,11 +1016,12 @@ double fn14(double i, double j) { // CHECK-NEXT: double _d_res = 0; // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: clad::tape _t2 = {}; -// CHECK-NEXT: clad::tape _t3 = {}; -// CHECK-NEXT: clad::tape _t5 = {}; -// CHECK-NEXT: clad::tape _t7 = {}; -// CHECK-NEXT: clad::tape _t8 = {}; -// CHECK-NEXT: clad::tape _t9 = {}; +// CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: clad::tape _t4 = {}; +// CHECK-NEXT: clad::tape _t6 = {}; +// CHECK-NEXT: clad::tape _t7 = {}; +// CHECK-NEXT: clad::tape _t9 = {}; +// CHECK-NEXT: clad::tape _t10 = {}; // CHECK-NEXT: int choice = 5; // CHECK-NEXT: double res = 0; // CHECK-NEXT: _t0 = 0; @@ -965,63 +1031,68 @@ double fn14(double i, double j) { // CHECK-NEXT: bool _t1 = choice > 3; // CHECK-NEXT: { // CHECK-NEXT: if (_t1) { +// CHECK-NEXT: clad::push(_t3, res); // CHECK-NEXT: res += i; // CHECK-NEXT: { -// CHECK-NEXT: clad::push(_t3, 1UL); +// CHECK-NEXT: clad::push(_t4, 1UL); // CHECK-NEXT: continue; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: clad::push(_t2, _t1); // CHECK-NEXT: } -// CHECK-NEXT: bool _t4 = choice > 1; +// CHECK-NEXT: bool _t5 = choice > 1; // CHECK-NEXT: { -// CHECK-NEXT: if (_t4) { +// CHECK-NEXT: if (_t5) { +// CHECK-NEXT: clad::push(_t7, res); // CHECK-NEXT: res += j; // CHECK-NEXT: { -// CHECK-NEXT: clad::push(_t3, 2UL); +// CHECK-NEXT: clad::push(_t4, 2UL); // CHECK-NEXT: continue; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t5, _t4); +// CHECK-NEXT: clad::push(_t6, _t5); // CHECK-NEXT: } -// CHECK-NEXT: bool _t6 = choice > 0; +// CHECK-NEXT: bool _t8 = choice > 0; // CHECK-NEXT: { -// CHECK-NEXT: if (_t6) { -// CHECK-NEXT: res += clad::push(_t9, i) * clad::push(_t8, j); +// CHECK-NEXT: if (_t8) { +// CHECK-NEXT: clad::push(_t10, res); +// CHECK-NEXT: res += i * j; // CHECK-NEXT: { -// CHECK-NEXT: clad::push(_t3, 3UL); +// CHECK-NEXT: clad::push(_t4, 3UL); // CHECK-NEXT: continue; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t7, _t6); +// CHECK-NEXT: clad::push(_t9, _t8); // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t3, 4UL); +// CHECK-NEXT: clad::push(_t4, 4UL); // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: while (_t0) // CHECK-NEXT: { -// CHECK-NEXT: switch (clad::pop(_t3)) { +// CHECK-NEXT: switch (clad::pop(_t4)) { // CHECK-NEXT: case 4UL: // CHECK-NEXT: ; -// CHECK-NEXT: if (clad::pop(_t7)) { +// CHECK-NEXT: if (clad::pop(_t9)) { // CHECK-NEXT: case 3UL: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t10); // CHECK-NEXT: double _r_d2 = _d_res; // CHECK-NEXT: _d_res += _r_d2; -// CHECK-NEXT: double _r0 = _r_d2 * clad::pop(_t8); +// CHECK-NEXT: double _r0 = _r_d2 * j; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = clad::pop(_t9) * _r_d2; +// CHECK-NEXT: double _r1 = i * _r_d2; // CHECK-NEXT: * _d_j += _r1; // CHECK-NEXT: _d_res -= _r_d2; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: if (clad::pop(_t5)) { +// CHECK-NEXT: if (clad::pop(_t6)) { // CHECK-NEXT: case 2UL: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t7); // CHECK-NEXT: double _r_d1 = _d_res; // CHECK-NEXT: _d_res += _r_d1; // CHECK-NEXT: * _d_j += _r_d1; @@ -1032,6 +1103,7 @@ double fn14(double i, double j) { // CHECK-NEXT: case 1UL: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t3); // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; // CHECK-NEXT: * _d_i += _r_d0; @@ -1069,11 +1141,15 @@ double fn15(double i, double j) { // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: clad::tape _t2 = {}; // CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: clad::tape _t4 = {}; // CHECK-NEXT: int _d_another_choice = 0; -// CHECK-NEXT: clad::tape _t4 = {}; -// CHECK-NEXT: clad::tape _t6 = {}; -// CHECK-NEXT: clad::tape _t7 = {}; -// CHECK-NEXT: clad::tape _t9 = {}; +// CHECK-NEXT: int another_choice = 0; +// CHECK-NEXT: clad::tape _t5 = {}; +// CHECK-NEXT: clad::tape _t7 = {}; +// CHECK-NEXT: clad::tape _t8 = {}; +// CHECK-NEXT: clad::tape _t9 = {}; +// CHECK-NEXT: clad::tape _t11 = {}; +// CHECK-NEXT: clad::tape _t12 = {}; // CHECK-NEXT: int choice = 5; // CHECK-NEXT: double res = 0; // CHECK-NEXT: _t0 = 0; @@ -1088,30 +1164,32 @@ double fn15(double i, double j) { // CHECK-NEXT: } // CHECK-NEXT: clad::push(_t2, _t1); // CHECK-NEXT: } -// CHECK-NEXT: int another_choice = 3; -// CHECK-NEXT: clad::push(_t4, 0UL); +// CHECK-NEXT: clad::push(_t4, another_choice) , another_choice = 3; +// CHECK-NEXT: clad::push(_t5, 0UL); // CHECK-NEXT: while (another_choice--) // CHECK-NEXT: { -// CHECK-NEXT: clad::back(_t4)++; -// CHECK-NEXT: bool _t5 = another_choice > 1; +// CHECK-NEXT: clad::back(_t5)++; +// CHECK-NEXT: bool _t6 = another_choice > 1; // CHECK-NEXT: { -// CHECK-NEXT: if (_t5) { +// CHECK-NEXT: if (_t6) { +// CHECK-NEXT: clad::push(_t8, res); // CHECK-NEXT: res += i; // CHECK-NEXT: { -// CHECK-NEXT: clad::push(_t7, 1UL); +// CHECK-NEXT: clad::push(_t9, 1UL); // CHECK-NEXT: continue; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t6, _t5); +// CHECK-NEXT: clad::push(_t7, _t6); // CHECK-NEXT: } -// CHECK-NEXT: bool _t8 = another_choice > 0; +// CHECK-NEXT: bool _t10 = another_choice > 0; // CHECK-NEXT: { -// CHECK-NEXT: if (_t8) { +// CHECK-NEXT: if (_t10) { +// CHECK-NEXT: clad::push(_t12, res); // CHECK-NEXT: res += j; // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t9, _t8); +// CHECK-NEXT: clad::push(_t11, _t10); // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t7, 2UL); +// CHECK-NEXT: clad::push(_t9, 2UL); // CHECK-NEXT: } // CHECK-NEXT: clad::push(_t3, 2UL); // CHECK-NEXT: } @@ -1124,23 +1202,25 @@ double fn15(double i, double j) { // CHECK-NEXT: case 2UL: // CHECK-NEXT: ; // CHECK-NEXT: { -// CHECK-NEXT: while (clad::back(_t4)) +// CHECK-NEXT: while (clad::back(_t5)) // CHECK-NEXT: { -// CHECK-NEXT: switch (clad::pop(_t7)) { +// CHECK-NEXT: switch (clad::pop(_t9)) { // CHECK-NEXT: case 2UL: // CHECK-NEXT: ; -// CHECK-NEXT: if (clad::pop(_t9)) { +// CHECK-NEXT: if (clad::pop(_t11)) { // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t12); // CHECK-NEXT: double _r_d1 = _d_res; // CHECK-NEXT: _d_res += _r_d1; // CHECK-NEXT: * _d_j += _r_d1; // CHECK-NEXT: _d_res -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: if (clad::pop(_t6)) { +// CHECK-NEXT: if (clad::pop(_t7)) { // CHECK-NEXT: case 1UL: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t8); // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; // CHECK-NEXT: * _d_i += _r_d0; @@ -1148,11 +1228,14 @@ double fn15(double i, double j) { // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: clad::back(_t4)--; +// CHECK-NEXT: clad::back(_t5)--; // CHECK-NEXT: } -// CHECK-NEXT: clad::pop(_t4); +// CHECK-NEXT: clad::pop(_t5); +// CHECK-NEXT: } +// CHECK-NEXT: { +// CHECK-NEXT: _d_another_choice = 0; +// CHECK-NEXT: another_choice = clad::pop(_t4); // CHECK-NEXT: } -// CHECK-NEXT: _d_another_choice = 0; // CHECK-NEXT: if (clad::pop(_t2)) // CHECK-NEXT: case 1UL: // CHECK-NEXT: ; @@ -1185,9 +1268,9 @@ double fn16(double i, double j) { // CHECK-NEXT: int _d_ii = 0; // CHECK-NEXT: clad::tape _t2 = {}; // CHECK-NEXT: clad::tape _t3 = {}; -// CHECK-NEXT: clad::tape _t4 = {}; -// CHECK-NEXT: clad::tape _t5 = {}; -// CHECK-NEXT: clad::tape _t7 = {}; +// CHECK-NEXT: clad::tape _t4 = {}; +// CHECK-NEXT: clad::tape _t6 = {}; +// CHECK-NEXT: clad::tape _t7 = {}; // CHECK-NEXT: clad::tape _t8 = {}; // CHECK-NEXT: int counter = 5; // CHECK-NEXT: double res = 0; @@ -1197,49 +1280,55 @@ double fn16(double i, double j) { // CHECK-NEXT: bool _t1 = ii == 4; // CHECK-NEXT: { // CHECK-NEXT: if (_t1) { -// CHECK-NEXT: res += clad::push(_t4, i) * clad::push(_t3, j); +// CHECK-NEXT: clad::push(_t3, res); +// CHECK-NEXT: res += i * j; // CHECK-NEXT: { -// CHECK-NEXT: clad::push(_t5, 1UL); +// CHECK-NEXT: clad::push(_t4, 1UL); // CHECK-NEXT: break; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: clad::push(_t2, _t1); // CHECK-NEXT: } -// CHECK-NEXT: bool _t6 = ii > 2; +// CHECK-NEXT: bool _t5 = ii > 2; // CHECK-NEXT: { -// CHECK-NEXT: if (_t6) { -// CHECK-NEXT: res += 2 * clad::push(_t8, i); +// CHECK-NEXT: if (_t5) { +// CHECK-NEXT: clad::push(_t7, res); +// CHECK-NEXT: res += 2 * i; // CHECK-NEXT: { -// CHECK-NEXT: clad::push(_t5, 2UL); +// CHECK-NEXT: clad::push(_t4, 2UL); // CHECK-NEXT: continue; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t7, _t6); +// CHECK-NEXT: clad::push(_t6, _t5); // CHECK-NEXT: } +// CHECK-NEXT: clad::push(_t8, res); // CHECK-NEXT: res += i + j; -// CHECK-NEXT: clad::push(_t5, 3UL); +// CHECK-NEXT: clad::push(_t4, 3UL); // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: for (; _t0; _t0--) -// CHECK-NEXT: switch (clad::pop(_t5)) { +// CHECK-NEXT: switch (clad::pop(_t4)) { // CHECK-NEXT: case 3UL: // CHECK-NEXT: ; +// CHECK-NEXT: --ii; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t8); // CHECK-NEXT: double _r_d2 = _d_res; // CHECK-NEXT: _d_res += _r_d2; // CHECK-NEXT: * _d_i += _r_d2; // CHECK-NEXT: * _d_j += _r_d2; // CHECK-NEXT: _d_res -= _r_d2; // CHECK-NEXT: } -// CHECK-NEXT: if (clad::pop(_t7)) { +// CHECK-NEXT: if (clad::pop(_t6)) { // CHECK-NEXT: case 2UL: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t7); // CHECK-NEXT: double _r_d1 = _d_res; // CHECK-NEXT: _d_res += _r_d1; -// CHECK-NEXT: double _r2 = _r_d1 * clad::pop(_t8); +// CHECK-NEXT: double _r2 = _r_d1 * i; // CHECK-NEXT: double _r3 = 2 * _r_d1; // CHECK-NEXT: * _d_i += _r3; // CHECK-NEXT: _d_res -= _r_d1; @@ -1249,11 +1338,12 @@ double fn16(double i, double j) { // CHECK-NEXT: case 1UL: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t3); // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; -// CHECK-NEXT: double _r0 = _r_d0 * clad::pop(_t3); +// CHECK-NEXT: double _r0 = _r_d0 * j; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = clad::pop(_t4) * _r_d0; +// CHECK-NEXT: double _r1 = i * _r_d0; // CHECK-NEXT: * _d_j += _r1; // CHECK-NEXT: _d_res -= _r_d0; // CHECK-NEXT: } @@ -1286,42 +1376,39 @@ double fn17(double i, double j) { // CHECK-NEXT: double _d_res = 0; // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_ii = 0; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: int _d_jj = 0; -// CHECK-NEXT: clad::tape _t2 = {}; -// CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: int jj = 0; +// CHECK-NEXT: clad::tape _t3 = {}; // CHECK-NEXT: clad::tape _t4 = {}; -// CHECK-NEXT: clad::tape _t6 = {}; -// CHECK-NEXT: clad::tape _t7 = {}; +// CHECK-NEXT: clad::tape _t5 = {}; +// CHECK-NEXT: clad::tape _t7 = {}; // CHECK-NEXT: clad::tape _t8 = {}; // CHECK-NEXT: clad::tape _t9 = {}; // CHECK-NEXT: clad::tape _t10 = {}; -// CHECK-NEXT: clad::tape _t11 = {}; -// CHECK-NEXT: clad::tape _t12 = {}; -// CHECK-NEXT: clad::tape _t13 = {}; -// CHECK-NEXT: clad::tape _t14 = {}; -// CHECK-NEXT: clad::tape _t15 = {}; // CHECK-NEXT: int counter = 5; // CHECK-NEXT: double res = 0; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: for (int ii = 0; ii < counter; ++ii) { // CHECK-NEXT: _t0++; -// CHECK-NEXT: int jj = ii; -// CHECK-NEXT: bool _t1 = ii < 2; +// CHECK-NEXT: clad::push(_t1, jj) , jj = ii; +// CHECK-NEXT: bool _t2 = ii < 2; // CHECK-NEXT: { -// CHECK-NEXT: if (_t1) { -// CHECK-NEXT: clad::push(_t3, 1UL); +// CHECK-NEXT: if (_t2) { +// CHECK-NEXT: clad::push(_t4, 1UL); // CHECK-NEXT: continue; // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t2, _t1); +// CHECK-NEXT: clad::push(_t3, _t2); // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t4, 0UL); +// CHECK-NEXT: clad::push(_t5, 0UL); // CHECK-NEXT: while (jj--) // CHECK-NEXT: { -// CHECK-NEXT: clad::back(_t4)++; -// CHECK-NEXT: bool _t5 = jj < 3; +// CHECK-NEXT: clad::back(_t5)++; +// CHECK-NEXT: bool _t6 = jj < 3; // CHECK-NEXT: { -// CHECK-NEXT: if (_t5) { -// CHECK-NEXT: res += clad::push(_t8, i) * clad::push(_t7, j); +// CHECK-NEXT: if (_t6) { +// CHECK-NEXT: clad::push(_t8, res); +// CHECK-NEXT: res += i * j; // CHECK-NEXT: { // CHECK-NEXT: clad::push(_t9, 1UL); // CHECK-NEXT: break; @@ -1332,50 +1419,54 @@ double fn17(double i, double j) { // CHECK-NEXT: continue; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t6, _t5); +// CHECK-NEXT: clad::push(_t7, _t6); // CHECK-NEXT: } -// CHECK-NEXT: res += clad::push(_t15, clad::push(_t14, clad::push(_t13, i) * clad::push(_t12, i)) * clad::push(_t11, j)) * clad::push(_t10, j); +// CHECK-NEXT: clad::push(_t10, res); +// CHECK-NEXT: res += i * i * j * j; // CHECK-NEXT: clad::push(_t9, 3UL); // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t3, 2UL); +// CHECK-NEXT: clad::push(_t4, 2UL); // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: for (; _t0; _t0--) -// CHECK-NEXT: switch (clad::pop(_t3)) { +// CHECK-NEXT: switch (clad::pop(_t4)) { // CHECK-NEXT: case 2UL: // CHECK-NEXT: ; +// CHECK-NEXT: --ii; // CHECK-NEXT: { -// CHECK-NEXT: while (clad::back(_t4)) +// CHECK-NEXT: while (clad::back(_t5)) // CHECK-NEXT: { // CHECK-NEXT: switch (clad::pop(_t9)) { // CHECK-NEXT: case 3UL: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t10); // CHECK-NEXT: double _r_d1 = _d_res; // CHECK-NEXT: _d_res += _r_d1; -// CHECK-NEXT: double _r2 = _r_d1 * clad::pop(_t10); -// CHECK-NEXT: double _r3 = _r2 * clad::pop(_t11); -// CHECK-NEXT: double _r4 = _r3 * clad::pop(_t12); +// CHECK-NEXT: double _r2 = _r_d1 * j; +// CHECK-NEXT: double _r3 = _r2 * j; +// CHECK-NEXT: double _r4 = _r3 * i; // CHECK-NEXT: * _d_i += _r4; -// CHECK-NEXT: double _r5 = clad::pop(_t13) * _r3; +// CHECK-NEXT: double _r5 = i * _r3; // CHECK-NEXT: * _d_i += _r5; -// CHECK-NEXT: double _r6 = clad::pop(_t14) * _r2; +// CHECK-NEXT: double _r6 = i * i * _r2; // CHECK-NEXT: * _d_j += _r6; -// CHECK-NEXT: double _r7 = clad::pop(_t15) * _r_d1; +// CHECK-NEXT: double _r7 = i * i * j * _r_d1; // CHECK-NEXT: * _d_j += _r7; // CHECK-NEXT: _d_res -= _r_d1; // CHECK-NEXT: } -// CHECK-NEXT: if (clad::pop(_t6)) { +// CHECK-NEXT: if (clad::pop(_t7)) { // CHECK-NEXT: case 1UL: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t8); // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; -// CHECK-NEXT: double _r0 = _r_d0 * clad::pop(_t7); +// CHECK-NEXT: double _r0 = _r_d0 * j; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = clad::pop(_t8) * _r_d0; +// CHECK-NEXT: double _r1 = i * _r_d0; // CHECK-NEXT: * _d_j += _r1; // CHECK-NEXT: _d_res -= _r_d0; // CHECK-NEXT: } @@ -1384,16 +1475,17 @@ double fn17(double i, double j) { // CHECK-NEXT: ; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: clad::back(_t4)--; +// CHECK-NEXT: clad::back(_t5)--; // CHECK-NEXT: } -// CHECK-NEXT: clad::pop(_t4); +// CHECK-NEXT: clad::pop(_t5); // CHECK-NEXT: } -// CHECK-NEXT: if (clad::pop(_t2)) +// CHECK-NEXT: if (clad::pop(_t3)) // CHECK-NEXT: case 1UL: // CHECK-NEXT: ; // CHECK-NEXT: { // CHECK-NEXT: _d_ii += _d_jj; // CHECK-NEXT: _d_jj = 0; +// CHECK-NEXT: jj = clad::pop(_t1); // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: } @@ -1419,9 +1511,9 @@ double fn18(double i, double j) { // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_counter = 0; // CHECK-NEXT: clad::tape _t2 = {}; -// CHECK-NEXT: clad::tape _t4 = {}; -// CHECK-NEXT: clad::tape _t5 = {}; -// CHECK-NEXT: clad::tape _t6 = {}; +// CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: clad::tape _t5 = {}; +// CHECK-NEXT: clad::tape _t6 = {}; // CHECK-NEXT: clad::tape _t7 = {}; // CHECK-NEXT: int choice = 5; // CHECK-NEXT: double res = 0; @@ -1430,54 +1522,59 @@ double fn18(double i, double j) { // CHECK-NEXT: _t0++; // CHECK-NEXT: bool _t1 = counter < 2; // CHECK-NEXT: { -// CHECK-NEXT: if (_t1) +// CHECK-NEXT: if (_t1) { +// CHECK-NEXT: clad::push(_t3, res); // CHECK-NEXT: res += i + j; -// CHECK-NEXT: else { -// CHECK-NEXT: bool _t3 = counter < 4; +// CHECK-NEXT: } else { +// CHECK-NEXT: bool _t4 = counter < 4; // CHECK-NEXT: { -// CHECK-NEXT: if (_t3) { -// CHECK-NEXT: clad::push(_t5, 1UL); +// CHECK-NEXT: if (_t4) { +// CHECK-NEXT: clad::push(_t6, 1UL); // CHECK-NEXT: continue; // CHECK-NEXT: } else { -// CHECK-NEXT: res += 2 * clad::push(_t6, i) + 2 * clad::push(_t7, j); +// CHECK-NEXT: clad::push(_t7, res); +// CHECK-NEXT: res += 2 * i + 2 * j; // CHECK-NEXT: { -// CHECK-NEXT: clad::push(_t5, 2UL); +// CHECK-NEXT: clad::push(_t6, 2UL); // CHECK-NEXT: break; // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t4, _t3); +// CHECK-NEXT: clad::push(_t5, _t4); // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: clad::push(_t2, _t1); // CHECK-NEXT: } -// CHECK-NEXT: clad::push(_t5, 3UL); +// CHECK-NEXT: clad::push(_t6, 3UL); // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: for (; _t0; _t0--) -// CHECK-NEXT: switch (clad::pop(_t5)) { +// CHECK-NEXT: switch (clad::pop(_t6)) { // CHECK-NEXT: case 3UL: // CHECK-NEXT: ; +// CHECK-NEXT: --counter; // CHECK-NEXT: if (clad::pop(_t2)) { +// CHECK-NEXT: res = clad::pop(_t3); // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; // CHECK-NEXT: * _d_i += _r_d0; // CHECK-NEXT: * _d_j += _r_d0; // CHECK-NEXT: _d_res -= _r_d0; -// CHECK-NEXT: } else if (clad::pop(_t4)) +// CHECK-NEXT: } else if (clad::pop(_t5)) // CHECK-NEXT: case 1UL: // CHECK-NEXT: ; // CHECK-NEXT: else { // CHECK-NEXT: case 2UL: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t7); // CHECK-NEXT: double _r_d1 = _d_res; // CHECK-NEXT: _d_res += _r_d1; -// CHECK-NEXT: double _r0 = _r_d1 * clad::pop(_t6); +// CHECK-NEXT: double _r0 = _r_d1 * i; // CHECK-NEXT: double _r1 = 2 * _r_d1; // CHECK-NEXT: * _d_i += _r1; -// CHECK-NEXT: double _r2 = _r_d1 * clad::pop(_t7); +// CHECK-NEXT: double _r2 = _r_d1 * j; // CHECK-NEXT: double _r3 = 2 * _r_d1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: _d_res -= _r_d1; @@ -1500,28 +1597,30 @@ double fn19(double* arr, int n) { // CHECK-NEXT: double _d_res = 0; // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: double *_d_ref = 0; +// CHECK-NEXT: clad::tape _t3 = {}; // CHECK-NEXT: double res = 0; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: for (int i = 0; i < n; ++i) { // CHECK-NEXT: _t0++; // CHECK-NEXT: _d_ref = &_d_arr[i]; -// CHECK-NEXT: clad::push(_t3, _d_ref); -// CHECK-NEXT: double &ref = arr[clad::push(_t1, i)]; +// CHECK-NEXT: clad::push(_t1, _d_ref); +// CHECK-NEXT: double &ref = arr[i]; +// CHECK-NEXT: clad::push(_t3, res); // CHECK-NEXT: res += ref; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: for (; _t0; _t0--) { -// CHECK-NEXT: double *_t4 = clad::pop(_t3); +// CHECK-NEXT: --i; +// CHECK-NEXT: double *_t2 = clad::pop(_t1); // CHECK-NEXT: { -// CHECK-NEXT: int _t2 = clad::pop(_t1); +// CHECK-NEXT: res = clad::pop(_t3); // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; -// CHECK-NEXT: *_t4 += _r_d0; +// CHECK-NEXT: *_t2 += _r_d0; // CHECK-NEXT: _d_res -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: } @@ -1541,48 +1640,45 @@ double f_loop_init_var(double lower, double upper) { // CHECK-NEXT: double _d_sum = 0; // CHECK-NEXT: double _d_num_points = 0; // CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; // CHECK-NEXT: double _d_interval = 0; -// CHECK-NEXT: unsigned long _t2; +// CHECK-NEXT: unsigned long _t1; // CHECK-NEXT: double _d_x = 0; +// CHECK-NEXT: clad::tape _t2 = {}; // CHECK-NEXT: clad::tape _t3 = {}; -// CHECK-NEXT: clad::tape _t4 = {}; -// CHECK-NEXT: clad::tape _t5 = {}; -// CHECK-NEXT: clad::tape _t6 = {}; // CHECK-NEXT: double sum = 0; // CHECK-NEXT: double num_points = 10000; -// CHECK-NEXT: _t1 = (upper - lower); // CHECK-NEXT: _t0 = num_points; -// CHECK-NEXT: double interval = _t1 / _t0; -// CHECK-NEXT: _t2 = 0; -// CHECK-NEXT: for (double x = lower; x <= upper; x += interval) { -// CHECK-NEXT: _t2++; -// CHECK-NEXT: sum += clad::push(_t6, clad::push(_t5, x) * clad::push(_t4, x)) * clad::push(_t3, interval); +// CHECK-NEXT: double interval = (upper - lower) / _t0; +// CHECK-NEXT: _t1 = 0; +// CHECK-NEXT: for (double x = lower; x <= upper; clad::push(_t2, x) , (x += interval)) { +// CHECK-NEXT: _t1++; +// CHECK-NEXT: clad::push(_t3, sum); +// CHECK-NEXT: sum += x * x * interval; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_sum += 1; // CHECK-NEXT: { -// CHECK-NEXT: for (; _t2; _t2--) { +// CHECK-NEXT: for (; _t1; _t1--) { // CHECK-NEXT: { +// CHECK-NEXT: x = clad::pop(_t2); // CHECK-NEXT: double _r_d0 = _d_x; // CHECK-NEXT: _d_x += _r_d0; // CHECK-NEXT: _d_interval += _r_d0; // CHECK-NEXT: _d_x -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: { -// CHECK-NEXT: double _r_d1 = _d_sum; -// CHECK-NEXT: _d_sum += _r_d1; -// CHECK-NEXT: double _r2 = _r_d1 * clad::pop(_t3); -// CHECK-NEXT: double _r3 = _r2 * clad::pop(_t4); -// CHECK-NEXT: _d_x += _r3; -// CHECK-NEXT: double _r4 = clad::pop(_t5) * _r2; -// CHECK-NEXT: _d_x += _r4; -// CHECK-NEXT: double _r5 = clad::pop(_t6) * _r_d1; -// CHECK-NEXT: _d_interval += _r5; -// CHECK-NEXT: _d_sum -= _r_d1; -// CHECK-NEXT: } +// CHECK-NEXT: sum = clad::pop(_t3); +// CHECK-NEXT: double _r_d1 = _d_sum; +// CHECK-NEXT: _d_sum += _r_d1; +// CHECK-NEXT: double _r2 = _r_d1 * interval; +// CHECK-NEXT: double _r3 = _r2 * x; +// CHECK-NEXT: _d_x += _r3; +// CHECK-NEXT: double _r4 = x * _r2; +// CHECK-NEXT: _d_x += _r4; +// CHECK-NEXT: double _r5 = x * x * _r_d1; +// CHECK-NEXT: _d_interval += _r5; +// CHECK-NEXT: _d_sum -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: * _d_lower += _d_x; @@ -1591,7 +1687,7 @@ double f_loop_init_var(double lower, double upper) { // CHECK-NEXT: double _r0 = _d_interval / _t0; // CHECK-NEXT: * _d_upper += _r0; // CHECK-NEXT: * _d_lower += -_r0; -// CHECK-NEXT: double _r1 = _d_interval * -_t1 / (_t0 * _t0); +// CHECK-NEXT: double _r1 = _d_interval * -(upper - lower) / (_t0 * _t0); // CHECK-NEXT: _d_num_points += _r1; // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Gradient/MemberFunctions.C b/test/Gradient/MemberFunctions.C index 1b0582fef..63ee00a69 100644 --- a/test/Gradient/MemberFunctions.C +++ b/test/Gradient/MemberFunctions.C @@ -1,9 +1,17 @@ // RUN: %cladclang %s -fno-exceptions -I%S/../../include -oMemberFunctions.out 2>&1 | FileCheck %s // RUN: ./MemberFunctions.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -fno-exceptions -I%S/../../include -oMemberFunctions.out +// RUN: ./MemberFunctions.out | FileCheck -check-prefix=CHECK-EXEC %s + // RUN: %cladclang -std=c++14 %s -fno-exceptions -I%S/../../include -oMemberFunctions-cpp14.out 2>&1 | FileCheck %s // RUN: ./MemberFunctions-cpp14.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr -std=c++14 %s -fno-exceptions -I%S/../../include -oMemberFunctions-cpp14.out +// RUN: ./MemberFunctions-cpp14.out | FileCheck -check-prefix=CHECK-EXEC %s + // RUN: %cladclang -std=c++17 %s -fno-exceptions -I%S/../../include -oMemberFunctions-cpp17.out 2>&1 | FileCheck %s // RUN: ./MemberFunctions-cpp17.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr -std=c++17 %s -fno-exceptions -I%S/../../include -oMemberFunctions-cpp17.out +// RUN: ./MemberFunctions-cpp17.out | FileCheck -check-prefix=CHECK-EXEC %s // XFAIL: asserts @@ -17,25 +25,17 @@ public: double mem_fn(double i, double j) { return (x + y) * i + i * j; } // CHECK: void mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -43,25 +43,17 @@ public: double const_mem_fn(double i, double j) const { return (x + y) * i + i * j; } // CHECK: void const_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -71,25 +63,17 @@ public: } // CHECK: void volatile_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -99,25 +83,17 @@ public: } // CHECK: void const_volatile_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -125,25 +101,17 @@ public: double lval_ref_mem_fn(double i, double j) & { return (x + y) * i + i * j; } // CHECK: void lval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) & { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -153,25 +121,17 @@ public: } // CHECK: void const_lval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const & { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -181,25 +141,17 @@ public: } // CHECK: void volatile_lval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile & { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -209,25 +161,17 @@ public: } // CHECK: void const_volatile_lval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile & { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -235,25 +179,17 @@ public: double rval_ref_mem_fn(double i, double j) && { return (x + y) * i + i * j; } // CHECK: void rval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) && { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -263,25 +199,17 @@ public: } // CHECK: void const_rval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const && { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -291,25 +219,17 @@ public: } // CHECK: void volatile_rval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile && { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -319,25 +239,17 @@ public: } // CHECK: void const_volatile_rval_ref_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile && { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -347,25 +259,17 @@ public: } // CHECK: void noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -375,25 +279,17 @@ public: } // CHECK: void const_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -403,25 +299,17 @@ public: } // CHECK: void volatile_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -431,25 +319,17 @@ public: } // CHECK: void const_volatile_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -459,25 +339,17 @@ public: } // CHECK: void lval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) & noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -487,25 +359,17 @@ public: } // CHECK: void const_lval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const & noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -515,25 +379,17 @@ public: } // CHECK: void volatile_lval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile & noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -543,25 +399,17 @@ public: } // CHECK: void const_volatile_lval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile & noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -571,25 +419,17 @@ public: } // CHECK: void rval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) && noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -599,25 +439,17 @@ public: } // CHECK: void const_rval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const && noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -627,25 +459,17 @@ public: } // CHECK: void volatile_rval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) volatile && noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -655,25 +479,17 @@ public: } // CHECK: void const_volatile_rval_ref_noexcept_mem_fn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile && noexcept { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -682,25 +498,17 @@ public: // CHECK: void partial_mem_fn_grad_0(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i) { // CHECK-NEXT: double _d_j = 0; - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -751,23 +559,15 @@ double fn(double i,double j) { } // CHECK: void fn_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: _t2 = i; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t3 = _t2 * _t1; -// CHECK-NEXT: _t0 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; -// CHECK-NEXT: double _r1 = _r0 * _t1; +// CHECK-NEXT: double _r0 = 1 * j; +// CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: * _d_i += _r1; -// CHECK-NEXT: double _r2 = _t2 * _r0; +// CHECK-NEXT: double _r2 = i * _r0; // CHECK-NEXT: * _d_i += _r2; -// CHECK-NEXT: double _r3 = _t3 * 1; +// CHECK-NEXT: double _r3 = i * i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -777,17 +577,23 @@ double fn2(SimpleFunctions& sf, double i) { } // CHECK: void ref_mem_fn_pullback(double i, double _d_y, clad::array_ref _d_this, clad::array_ref _d_i) { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: double _t1; +// CHECK-NEXT: _t0 = this->x; // CHECK-NEXT: this->x = +i; +// CHECK-NEXT: _t1 = this->x; // CHECK-NEXT: this->x = -i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: (* _d_this).x += _d_y; // CHECK-NEXT: { +// CHECK-NEXT: this->x = _t1; // CHECK-NEXT: double _r_d1 = (* _d_this).x; // CHECK-NEXT: * _d_i += -_r_d1; // CHECK-NEXT: (* _d_this).x -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: this->x = _t0; // CHECK-NEXT: double _r_d0 = (* _d_this).x; // CHECK-NEXT: * _d_i += _r_d0; // CHECK-NEXT: (* _d_this).x -= _r_d0; @@ -795,22 +601,24 @@ double fn2(SimpleFunctions& sf, double i) { // CHECK-NEXT: } // CHECK: clad::ValueAndAdjoint ref_mem_fn_forw(double i, clad::array_ref _d_this, clad::array_ref _d_i) { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: double _t1; +// CHECK-NEXT: _t0 = this->x; // CHECK-NEXT: this->x = +i; +// CHECK-NEXT: _t1 = this->x; // CHECK-NEXT: this->x = -i; // CHECK-NEXT: return {this->x, (* _d_this).x}; // CHECK-NEXT: } // CHECK: void fn2_grad(SimpleFunctions &sf, double i, clad::array_ref _d_sf, clad::array_ref _d_i) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: SimpleFunctions _t1; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t1 = sf; -// CHECK-NEXT: clad::ValueAndAdjoint _t2 = _t1.ref_mem_fn_forw(_t0, &(* _d_sf), nullptr); +// CHECK-NEXT: SimpleFunctions _t0; +// CHECK-NEXT: _t0 = sf; +// CHECK-NEXT: clad::ValueAndAdjoint _t1 = _t0.ref_mem_fn_forw(i, &(* _d_sf), nullptr); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: double _grad0 = 0.; -// CHECK-NEXT: _t1.ref_mem_fn_pullback(_t0, 1, &(* _d_sf), &_grad0); +// CHECK-NEXT: _t0.ref_mem_fn_pullback(i, 1, &(* _d_sf), &_grad0); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: * _d_i += _r0; // CHECK-NEXT: } @@ -827,11 +635,14 @@ double fn5(SimpleFunctions& v, double value) { } // CHECK: void operator_plus_equal_pullback(double value, SimpleFunctions _d_y, clad::array_ref _d_this, clad::array_ref _d_value) { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: _t0 = this->x; // CHECK-NEXT: this->x += value; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: this->x = _t0; // CHECK-NEXT: double _r_d0 = (* _d_this).x; // CHECK-NEXT: (* _d_this).x += _r_d0; // CHECK-NEXT: * _d_value += _r_d0; @@ -840,22 +651,22 @@ double fn5(SimpleFunctions& v, double value) { // CHECK-NEXT: } // CHECK: clad::ValueAndAdjoint operator_plus_equal_forw(double value, clad::array_ref _d_this, clad::array_ref _d_value) { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: _t0 = this->x; // CHECK-NEXT: this->x += value; // CHECK-NEXT: return {*this, (* _d_this)}; // CHECK-NEXT: } // CHECK: void fn5_grad(SimpleFunctions &v, double value, clad::array_ref _d_v, clad::array_ref _d_value) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: SimpleFunctions _t1; -// CHECK-NEXT: _t0 = value; -// CHECK-NEXT: _t1 = v; -// CHECK-NEXT: clad::ValueAndAdjoint _t2 = _t1.operator_plus_equal_forw(_t0, &(* _d_v), nullptr); +// CHECK-NEXT: SimpleFunctions _t0; +// CHECK-NEXT: _t0 = v; +// CHECK-NEXT: clad::ValueAndAdjoint _t1 = _t0.operator_plus_equal_forw(value, &(* _d_v), nullptr); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: (* _d_v).x += 1; // CHECK-NEXT: { // CHECK-NEXT: double _grad0 = 0.; -// CHECK-NEXT: _t1.operator_plus_equal_pullback(_t0, {}, &(* _d_v), &_grad0); +// CHECK-NEXT: _t0.operator_plus_equal_pullback(value, {}, &(* _d_v), &_grad0); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: * _d_value += _r0; // CHECK-NEXT: } @@ -867,11 +678,14 @@ double fn4(SimpleFunctions& v) { } // CHECK: void operator_plus_plus_pullback(SimpleFunctions _d_y, clad::array_ref _d_this) { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: _t0 = this->x; // CHECK-NEXT: this->x += 1.; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: ; // CHECK-NEXT: { +// CHECK-NEXT: this->x = _t0; // CHECK-NEXT: double _r_d0 = (* _d_this).x; // CHECK-NEXT: (* _d_this).x += _r_d0; // CHECK-NEXT: (* _d_this).x -= _r_d0; @@ -879,6 +693,8 @@ double fn4(SimpleFunctions& v) { // CHECK-NEXT: } // CHECK: clad::ValueAndAdjoint operator_plus_plus_forw(clad::array_ref _d_this) { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: _t0 = this->x; // CHECK-NEXT: this->x += 1.; // CHECK-NEXT: return {*this, (* _d_this)}; // CHECK-NEXT: } @@ -946,25 +762,17 @@ int main() { // CHECK: void const_volatile_lval_ref_mem_fn_grad_0(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i) const volatile & { // CHECK-NEXT: double _d_j = 0; - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: * _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: * _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -973,25 +781,17 @@ int main() { // CHECK: void const_volatile_rval_ref_mem_fn_grad_1(double i, double j, clad::array_ref _d_this, clad::array_ref _d_j) const volatile && { // CHECK-NEXT: double _d_i = 0; - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: _t1 = (this->x + this->y); - // CHECK-NEXT: _t0 = i; - // CHECK-NEXT: _t3 = i; - // CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; - // CHECK-NEXT: _label0: + // CHECK-NEXT: _label0: // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; + // CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).x += _r0; // CHECK-NEXT: (* _d_this).y += _r0; - // CHECK-NEXT: double _r1 = _t1 * 1; + // CHECK-NEXT: double _r1 = (this->x + this->y) * 1; // CHECK-NEXT: _d_i += _r1; - // CHECK-NEXT: double _r2 = 1 * _t2; + // CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: _d_i += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: * _d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -1005,19 +805,15 @@ int main() { // CHECK-NEXT: double _d_x = 0; // CHECK-NEXT: double _d_y = 0; // CHECK-NEXT: SimpleFunctions _d_sf({}); -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: SimpleFunctions _t2; +// CHECK-NEXT: SimpleFunctions _t0; // CHECK-NEXT: SimpleFunctions sf(x, y); -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t1 = j; -// CHECK-NEXT: _t2 = sf; +// CHECK-NEXT: _t0 = sf; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: double _grad0 = 0.; // CHECK-NEXT: double _grad1 = 0.; -// CHECK-NEXT: _t2.mem_fn_pullback(_t0, _t1, 1, &_d_sf, &_grad0, &_grad1); +// CHECK-NEXT: _t0.mem_fn_pullback(i, j, 1, &_d_sf, &_grad0, &_grad1); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: * _d_i += _r0; // CHECK-NEXT: double _r1 = _grad1; diff --git a/test/Gradient/Pointers.C b/test/Gradient/Pointers.C index 50701f42e..199c3041e 100644 --- a/test/Gradient/Pointers.C +++ b/test/Gradient/Pointers.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oPointers.out 2>&1 | FileCheck %s // RUN: ./Pointers.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oPointers.out +// RUN: ./Pointers.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" @@ -7,18 +9,13 @@ double nonMemFn(double i) { return i*i; } - // CHECK: void nonMemFn_grad(double i, clad::array_ref _d_i) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t0 = i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; +// CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: * _d_i += _r0; -// CHECK-NEXT: double _r1 = _t1 * 1; +// CHECK-NEXT: double _r1 = i * 1; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Gradient/TemplateFunctors.C b/test/Gradient/TemplateFunctors.C index a7ede0364..2cbb65eeb 100644 --- a/test/Gradient/TemplateFunctors.C +++ b/test/Gradient/TemplateFunctors.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oTemplateFunctors.out 2>&1 | FileCheck %s // RUN: ./TemplateFunctors.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oTemplateFunctors.out +// RUN: ./TemplateFunctors.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" @@ -13,31 +15,19 @@ template struct Experiment { }; // CHECK: void operator_call_grad(double i, double j, clad::array_ref > _d_this, clad::array_ref _d_i, clad::array_ref _d_j) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: double _t5; -// CHECK-NEXT: _t2 = this->x; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t3 = _t2 * _t1; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t5 = this->y; -// CHECK-NEXT: _t4 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; -// CHECK-NEXT: double _r1 = _r0 * _t1; +// CHECK-NEXT: double _r0 = 1 * i; +// CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: (* _d_this).x += _r1; -// CHECK-NEXT: double _r2 = _t2 * _r0; +// CHECK-NEXT: double _r2 = this->x * _r0; // CHECK-NEXT: * _d_i += _r2; -// CHECK-NEXT: double _r3 = _t3 * 1; +// CHECK-NEXT: double _r3 = this->x * i * 1; // CHECK-NEXT: * _d_i += _r3; -// CHECK-NEXT: double _r4 = 1 * _t4; +// CHECK-NEXT: double _r4 = 1 * j; // CHECK-NEXT: (* _d_this).y += _r4; -// CHECK-NEXT: double _r5 = _t5 * 1; +// CHECK-NEXT: double _r5 = this->y * 1; // CHECK-NEXT: * _d_j += _r5; // CHECK-NEXT: } // CHECK-NEXT: } @@ -53,45 +43,25 @@ template <> struct Experiment { }; // CHECK: void operator_call_grad(long double i, long double j, clad::array_ref > _d_this, clad::array_ref _d_i, clad::array_ref _d_j) { -// CHECK-NEXT: long double _t0; -// CHECK-NEXT: long double _t1; -// CHECK-NEXT: long double _t2; -// CHECK-NEXT: long double _t3; -// CHECK-NEXT: long double _t4; -// CHECK-NEXT: long double _t5; -// CHECK-NEXT: long double _t6; -// CHECK-NEXT: long double _t7; -// CHECK-NEXT: long double _t8; -// CHECK-NEXT: long double _t9; -// CHECK-NEXT: _t3 = this->x; -// CHECK-NEXT: _t2 = i; -// CHECK-NEXT: _t4 = _t3 * _t2; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t5 = _t4 * _t1; -// CHECK-NEXT: _t0 = j; -// CHECK-NEXT: _t8 = this->y; -// CHECK-NEXT: _t7 = j; -// CHECK-NEXT: _t9 = _t8 * _t7; -// CHECK-NEXT: _t6 = i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: long double _r0 = 1 * _t0; -// CHECK-NEXT: long double _r1 = _r0 * _t1; -// CHECK-NEXT: long double _r2 = _r1 * _t2; +// CHECK-NEXT: long double _r0 = 1 * j; +// CHECK-NEXT: long double _r1 = _r0 * i; +// CHECK-NEXT: long double _r2 = _r1 * i; // CHECK-NEXT: (* _d_this).x += _r2; -// CHECK-NEXT: long double _r3 = _t3 * _r1; +// CHECK-NEXT: long double _r3 = this->x * _r1; // CHECK-NEXT: * _d_i += _r3; -// CHECK-NEXT: long double _r4 = _t4 * _r0; +// CHECK-NEXT: long double _r4 = this->x * i * _r0; // CHECK-NEXT: * _d_i += _r4; -// CHECK-NEXT: long double _r5 = _t5 * 1; +// CHECK-NEXT: long double _r5 = this->x * i * i * 1; // CHECK-NEXT: * _d_j += _r5; -// CHECK-NEXT: long double _r6 = 1 * _t6; -// CHECK-NEXT: long double _r7 = _r6 * _t7; +// CHECK-NEXT: long double _r6 = 1 * i; +// CHECK-NEXT: long double _r7 = _r6 * j; // CHECK-NEXT: (* _d_this).y += _r7; -// CHECK-NEXT: long double _r8 = _t8 * _r6; +// CHECK-NEXT: long double _r8 = this->y * _r6; // CHECK-NEXT: * _d_j += _r8; -// CHECK-NEXT: long double _r9 = _t9 * 1; +// CHECK-NEXT: long double _r9 = this->y * j * 1; // CHECK-NEXT: * _d_i += _r9; // CHECK-NEXT: } // CHECK-NEXT: } @@ -105,31 +75,19 @@ template struct ExperimentConstVolatile { }; // CHECK: void operator_call_grad(double i, double j, clad::array_ref > _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: volatile double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: volatile double _t5; -// CHECK-NEXT: _t2 = this->x; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t3 = _t2 * _t1; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t5 = this->y; -// CHECK-NEXT: _t4 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; -// CHECK-NEXT: double _r1 = _r0 * _t1; +// CHECK-NEXT: double _r0 = 1 * i; +// CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: (* _d_this).x += _r1; -// CHECK-NEXT: double _r2 = _t2 * _r0; +// CHECK-NEXT: double _r2 = this->x * _r0; // CHECK-NEXT: * _d_i += _r2; -// CHECK-NEXT: double _r3 = _t3 * 1; +// CHECK-NEXT: double _r3 = this->x * i * 1; // CHECK-NEXT: * _d_i += _r3; -// CHECK-NEXT: double _r4 = 1 * _t4; +// CHECK-NEXT: double _r4 = 1 * j; // CHECK-NEXT: (* _d_this).y += _r4; -// CHECK-NEXT: double _r5 = _t5 * 1; +// CHECK-NEXT: double _r5 = this->y * 1; // CHECK-NEXT: * _d_j += _r5; // CHECK-NEXT: } // CHECK-NEXT: } @@ -145,45 +103,25 @@ template <> struct ExperimentConstVolatile { }; // CHECK: void operator_call_grad(long double i, long double j, clad::array_ref > _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const volatile { -// CHECK-NEXT: long double _t0; -// CHECK-NEXT: long double _t1; -// CHECK-NEXT: long double _t2; -// CHECK-NEXT: volatile long double _t3; -// CHECK-NEXT: long double _t4; -// CHECK-NEXT: long double _t5; -// CHECK-NEXT: long double _t6; -// CHECK-NEXT: long double _t7; -// CHECK-NEXT: volatile long double _t8; -// CHECK-NEXT: long double _t9; -// CHECK-NEXT: _t3 = this->x; -// CHECK-NEXT: _t2 = i; -// CHECK-NEXT: _t4 = _t3 * _t2; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t5 = _t4 * _t1; -// CHECK-NEXT: _t0 = j; -// CHECK-NEXT: _t8 = this->y; -// CHECK-NEXT: _t7 = j; -// CHECK-NEXT: _t9 = _t8 * _t7; -// CHECK-NEXT: _t6 = i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: long double _r0 = 1 * _t0; -// CHECK-NEXT: long double _r1 = _r0 * _t1; -// CHECK-NEXT: long double _r2 = _r1 * _t2; +// CHECK-NEXT: long double _r0 = 1 * j; +// CHECK-NEXT: long double _r1 = _r0 * i; +// CHECK-NEXT: long double _r2 = _r1 * i; // CHECK-NEXT: (* _d_this).x += _r2; -// CHECK-NEXT: long double _r3 = _t3 * _r1; +// CHECK-NEXT: long double _r3 = this->x * _r1; // CHECK-NEXT: * _d_i += _r3; -// CHECK-NEXT: long double _r4 = _t4 * _r0; +// CHECK-NEXT: long double _r4 = this->x * i * _r0; // CHECK-NEXT: * _d_i += _r4; -// CHECK-NEXT: long double _r5 = _t5 * 1; +// CHECK-NEXT: long double _r5 = this->x * i * i * 1; // CHECK-NEXT: * _d_j += _r5; -// CHECK-NEXT: long double _r6 = 1 * _t6; -// CHECK-NEXT: long double _r7 = _r6 * _t7; +// CHECK-NEXT: long double _r6 = 1 * i; +// CHECK-NEXT: long double _r7 = _r6 * j; // CHECK-NEXT: (* _d_this).y += _r7; -// CHECK-NEXT: long double _r8 = _t8 * _r6; +// CHECK-NEXT: long double _r8 = this->y * _r6; // CHECK-NEXT: * _d_j += _r8; -// CHECK-NEXT: long double _r9 = _t9 * 1; +// CHECK-NEXT: long double _r9 = this->y * j * 1; // CHECK-NEXT: * _d_i += _r9; // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Gradient/TestAgainstDiff.C b/test/Gradient/TestAgainstDiff.C index 4c6445725..99fe2234d 100644 --- a/test/Gradient/TestAgainstDiff.C +++ b/test/Gradient/TestAgainstDiff.C @@ -1,6 +1,8 @@ // RUN: %cladclang %s -I%S/../../include -oTestAgainstDiff.out 2>&1 | FileCheck %s // RUN: ./TestAgainstDiff.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oTestAgainstDiff.out +// RUN: ./TestAgainstDiff.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" diff --git a/test/Gradient/TestTypeConversion.C b/test/Gradient/TestTypeConversion.C index d821e2742..bccbf2d91 100644 --- a/test/Gradient/TestTypeConversion.C +++ b/test/Gradient/TestTypeConversion.C @@ -1,5 +1,7 @@ // RUN: %cladnumdiffclang %s -I%S/../../include -oTestTypeConversion.out 2>&1 | FileCheck %s // RUN: ./TestTypeConversion.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladnumdiffclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oTestTypeConversion.out +// RUN: ./TestTypeConversion.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -19,22 +21,24 @@ void fn_type_conversion_grad(float z, int a, clad::array_ref _d_z, clad:: // CHECK: void fn_type_conversion_grad(float z, int a, clad::array_ref _d_z, clad::array_ref _d_a) { // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: clad::tape _t2 = {}; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: for (int i = 1; i < a; i++) { // CHECK-NEXT: _t0++; -// CHECK-NEXT: z = clad::push(_t2, z) * clad::push(_t1, a); +// CHECK-NEXT: clad::push(_t1, z); +// CHECK-NEXT: z = z * a; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: * _d_z += 1; // CHECK-NEXT: for (; _t0; _t0--) { +// CHECK-NEXT: i--; // CHECK-NEXT: { +// CHECK-NEXT: z = clad::pop(_t1); // CHECK-NEXT: float _r_d0 = * _d_z; -// CHECK-NEXT: float _r0 = _r_d0 * clad::pop(_t1); +// CHECK-NEXT: float _r0 = _r_d0 * a; // CHECK-NEXT: * _d_z += _r0; -// CHECK-NEXT: float _r1 = clad::pop(_t2) * _r_d0; +// CHECK-NEXT: float _r1 = z * _r_d0; // CHECK-NEXT: * _d_a += _r1; // CHECK-NEXT: * _d_z -= _r_d0; // CHECK-NEXT: * _d_z; diff --git a/test/Gradient/UserDefinedTypes.C b/test/Gradient/UserDefinedTypes.C index 068c6ed06..eb819e862 100644 --- a/test/Gradient/UserDefinedTypes.C +++ b/test/Gradient/UserDefinedTypes.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oUserDefinedTypes.out 2>&1 | FileCheck %s // RUN: ./UserDefinedTypes.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oUserDefinedTypes.out +// RUN: ./UserDefinedTypes.out | FileCheck -check-prefix=CHECK-EXEC %s // XFAIL: asserts // CHECK-NOT: {{.*error|warning|note:.*}} @@ -19,21 +21,17 @@ double fn1(pairdd p, double i) { } // CHECK: void fn1_grad(pairdd p, double i, clad::array_ref _d_p, clad::array_ref _d_i) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; // CHECK-NEXT: double _d_res = 0; -// CHECK-NEXT: _t0 = p.second; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: double res = p.first + 2 * _t0 + 3 * _t1; +// CHECK-NEXT: double res = p.first + 2 * p.second + 3 * i; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: { // CHECK-NEXT: (* _d_p).first += _d_res; -// CHECK-NEXT: double _r0 = _d_res * _t0; +// CHECK-NEXT: double _r0 = _d_res * p.second; // CHECK-NEXT: double _r1 = 2 * _d_res; // CHECK-NEXT: (* _d_p).second += _r1; -// CHECK-NEXT: double _r2 = _d_res * _t1; +// CHECK-NEXT: double _r2 = _d_res * i; // CHECK-NEXT: double _r3 = 3 * _d_res; // CHECK-NEXT: * _d_i += _r3; // CHECK-NEXT: } @@ -66,21 +64,23 @@ double sum(Tangent& t) { // CHECK-NEXT: double _d_res = 0; // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: clad::tape _t1 = {}; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: double res = 0; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: for (int i = 0; i < 5; ++i) { // CHECK-NEXT: _t0++; -// CHECK-NEXT: res += t.data[clad::push(_t1, i)]; +// CHECK-NEXT: clad::push(_t1, res); +// CHECK-NEXT: res += t.data[i]; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += _d_y; // CHECK-NEXT: for (; _t0; _t0--) { +// CHECK-NEXT: --i; +// CHECK-NEXT: res = clad::pop(_t1); // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; -// CHECK-NEXT: int _t2 = clad::pop(_t1); -// CHECK-NEXT: (* _d_t).data[_t2] += _r_d0; +// CHECK-NEXT: (* _d_t).data[i] += _r_d0; // CHECK-NEXT: _d_res -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: } @@ -96,21 +96,23 @@ double sum(double *data) { // CHECK-NEXT: double _d_res = 0; // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: clad::tape _t1 = {}; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: double res = 0; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: for (int i = 0; i < 5; ++i) { // CHECK-NEXT: _t0++; -// CHECK-NEXT: res += data[clad::push(_t1, i)]; +// CHECK-NEXT: clad::push(_t1, res); +// CHECK-NEXT: res += data[i]; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += _d_y; // CHECK-NEXT: for (; _t0; _t0--) { +// CHECK-NEXT: --i; +// CHECK-NEXT: res = clad::pop(_t1); // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; -// CHECK-NEXT: int _t2 = clad::pop(_t1); -// CHECK-NEXT: _d_data[_t2] += _r_d0; +// CHECK-NEXT: _d_data[i] += _r_d0; // CHECK-NEXT: _d_res -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: } @@ -124,29 +126,29 @@ double fn2(Tangent t, double i) { // CHECK: void fn2_grad(Tangent t, double i, clad::array_ref _d_t, clad::array_ref _d_i) { // CHECK-NEXT: Tangent _t0; // CHECK-NEXT: double _d_res = 0; -// CHECK-NEXT: clad::array _t1(5UL); -// CHECK-NEXT: double _t3; +// CHECK-NEXT: double _t1; // CHECK-NEXT: _t0 = t; // CHECK-NEXT: double res = sum(t); -// CHECK-NEXT: _t1 = t.data; -// CHECK-NEXT: _t3 = t.data[0]; -// CHECK-NEXT: res += sum(t.data) + i + 2 * _t3; +// CHECK-NEXT: _t1 = res; +// CHECK-NEXT: res += sum(t.data) + i + 2 * t.data[0]; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: { +// CHECK-NEXT: res = _t1; // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; // CHECK-NEXT: clad::array_ref _t2 = {(* _d_t).data, 5UL}; -// CHECK-NEXT: sum_pullback(_t1, _r_d0, _t2); +// CHECK-NEXT: sum_pullback(t.data, _r_d0, _t2); // CHECK-NEXT: clad::array _r1({(* _d_t).data, 5UL}); // CHECK-NEXT: * _d_i += _r_d0; -// CHECK-NEXT: double _r2 = _r_d0 * _t3; +// CHECK-NEXT: double _r2 = _r_d0 * t.data[0]; // CHECK-NEXT: double _r3 = 2 * _r_d0; // CHECK-NEXT: (* _d_t).data[0] += _r3; // CHECK-NEXT: _d_res -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: t = _t0; // CHECK-NEXT: sum_pullback(_t0, _d_res, &(* _d_t)); // CHECK-NEXT: Tangent _r0 = (* _d_t); // CHECK-NEXT: } @@ -163,34 +165,35 @@ double fn3(double i, double j) { // CHECK-NEXT: Tangent _d_t({}); // CHECK-NEXT: double _t0; // CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: Tangent _t3; +// CHECK-NEXT: Tangent _t2; // CHECK-NEXT: Tangent t; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: t.data[0] = 2 * _t0; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t2 = j; -// CHECK-NEXT: t.data[1] = 5 * _t1 + 3 * _t2; -// CHECK-NEXT: _t3 = t; +// CHECK-NEXT: _t0 = t.data[0]; +// CHECK-NEXT: t.data[0] = 2 * i; +// CHECK-NEXT: _t1 = t.data[1]; +// CHECK-NEXT: t.data[1] = 5 * i + 3 * j; +// CHECK-NEXT: _t2 = t; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: sum_pullback(_t3, 1, &_d_t); +// CHECK-NEXT: t = _t2; +// CHECK-NEXT: sum_pullback(_t2, 1, &_d_t); // CHECK-NEXT: Tangent _r6 = _d_t; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: t.data[1] = _t1; // CHECK-NEXT: double _r_d1 = _d_t.data[1]; -// CHECK-NEXT: double _r2 = _r_d1 * _t1; +// CHECK-NEXT: double _r2 = _r_d1 * i; // CHECK-NEXT: double _r3 = 5 * _r_d1; // CHECK-NEXT: * _d_i += _r3; -// CHECK-NEXT: double _r4 = _r_d1 * _t2; +// CHECK-NEXT: double _r4 = _r_d1 * j; // CHECK-NEXT: double _r5 = 3 * _r_d1; // CHECK-NEXT: * _d_j += _r5; // CHECK-NEXT: _d_t.data[1] -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: { +// CHECK-NEXT: t.data[0] = _t0; // CHECK-NEXT: double _r_d0 = _d_t.data[0]; -// CHECK-NEXT: double _r0 = _r_d0 * _t0; +// CHECK-NEXT: double _r0 = _r_d0 * i; // CHECK-NEXT: double _r1 = 2 * _r_d0; // CHECK-NEXT: * _d_i += _r1; // CHECK-NEXT: _d_t.data[0] -= _r_d0; @@ -206,78 +209,48 @@ double fn4(double i, double j) { // CHECK: void fn4_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { // CHECK-NEXT: pairdd _d_p({}); // CHECK-NEXT: pairdd _d_q({}); -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: double _t5; -// CHECK-NEXT: double _t6; -// CHECK-NEXT: double _t7; // CHECK-NEXT: pairdd p(1, 3); // CHECK-NEXT: pairdd q({7, 5}); -// CHECK-NEXT: _t1 = p.first; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t3 = p.second; -// CHECK-NEXT: _t2 = j; -// CHECK-NEXT: _t5 = q.first; -// CHECK-NEXT: _t4 = i; -// CHECK-NEXT: _t7 = q.second; -// CHECK-NEXT: _t6 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; +// CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: _d_p.first += _r0; -// CHECK-NEXT: double _r1 = _t1 * 1; +// CHECK-NEXT: double _r1 = p.first * 1; // CHECK-NEXT: * _d_i += _r1; -// CHECK-NEXT: double _r2 = 1 * _t2; +// CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: _d_p.second += _r2; -// CHECK-NEXT: double _r3 = _t3 * 1; +// CHECK-NEXT: double _r3 = p.second * 1; // CHECK-NEXT: * _d_j += _r3; -// CHECK-NEXT: double _r4 = 1 * _t4; +// CHECK-NEXT: double _r4 = 1 * i; // CHECK-NEXT: _d_q.first += _r4; -// CHECK-NEXT: double _r5 = _t5 * 1; +// CHECK-NEXT: double _r5 = q.first * 1; // CHECK-NEXT: * _d_i += _r5; -// CHECK-NEXT: double _r6 = 1 * _t6; +// CHECK-NEXT: double _r6 = 1 * j; // CHECK-NEXT: _d_q.second += _r6; -// CHECK-NEXT: double _r7 = _t7 * 1; +// CHECK-NEXT: double _r7 = q.second * 1; // CHECK-NEXT: * _d_j += _r7; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: void someMemFn_grad(double i, double j, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: double _t5; -// CHECK-NEXT: double _t6; -// CHECK-NEXT: _t1 = this->data[0]; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t3 = this->data[1]; -// CHECK-NEXT: _t2 = j; -// CHECK-NEXT: _t4 = this->data[2]; -// CHECK-NEXT: _t6 = this->data[3]; -// CHECK-NEXT: _t5 = this->data[4]; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; +// CHECK-NEXT: double _r0 = 1 * i; // CHECK-NEXT: (* _d_this).data[0] += _r0; -// CHECK-NEXT: double _r1 = _t1 * 1; +// CHECK-NEXT: double _r1 = this->data[0] * 1; // CHECK-NEXT: * _d_i += _r1; -// CHECK-NEXT: double _r2 = 1 * _t2; +// CHECK-NEXT: double _r2 = 1 * j; // CHECK-NEXT: (* _d_this).data[1] += _r2; -// CHECK-NEXT: double _r3 = _t3 * 1; +// CHECK-NEXT: double _r3 = this->data[1] * 1; // CHECK-NEXT: * _d_j += _r3; -// CHECK-NEXT: double _r4 = 1 * _t4; +// CHECK-NEXT: double _r4 = 1 * this->data[2]; // CHECK-NEXT: double _r5 = 3 * 1; // CHECK-NEXT: (* _d_this).data[2] += _r5; -// CHECK-NEXT: double _r6 = 1 * _t5; +// CHECK-NEXT: double _r6 = 1 * this->data[4]; // CHECK-NEXT: (* _d_this).data[3] += _r6; -// CHECK-NEXT: double _r7 = _t6 * 1; +// CHECK-NEXT: double _r7 = this->data[3] * 1; // CHECK-NEXT: (* _d_this).data[4] += _r7; // CHECK-NEXT: } // CHECK-NEXT: } @@ -287,48 +260,32 @@ double fn5(const Tangent& t, double i) { } // CHECK: void someMemFn2_pullback(double i, double j, double _d_y, clad::array_ref _d_this, clad::array_ref _d_i, clad::array_ref _d_j) const { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: double _t5; -// CHECK-NEXT: _t1 = this->data[0]; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t4 = this->data[1]; -// CHECK-NEXT: _t3 = i; -// CHECK-NEXT: _t5 = _t4 * _t3; -// CHECK-NEXT: _t2 = j; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = _d_y * _t0; +// CHECK-NEXT: double _r0 = _d_y * i; // CHECK-NEXT: (* _d_this).data[0] += _r0; -// CHECK-NEXT: double _r1 = _t1 * _d_y; +// CHECK-NEXT: double _r1 = this->data[0] * _d_y; // CHECK-NEXT: * _d_i += _r1; -// CHECK-NEXT: double _r2 = _d_y * _t2; -// CHECK-NEXT: double _r3 = _r2 * _t3; +// CHECK-NEXT: double _r2 = _d_y * j; +// CHECK-NEXT: double _r3 = _r2 * i; // CHECK-NEXT: (* _d_this).data[1] += _r3; -// CHECK-NEXT: double _r4 = _t4 * _r2; +// CHECK-NEXT: double _r4 = this->data[1] * _r2; // CHECK-NEXT: * _d_i += _r4; -// CHECK-NEXT: double _r5 = _t5 * _d_y; +// CHECK-NEXT: double _r5 = this->data[1] * i * _d_y; // CHECK-NEXT: * _d_j += _r5; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: void fn5_grad(const Tangent &t, double i, clad::array_ref _d_t, clad::array_ref _d_i) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: Tangent _t2; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t2 = t; +// CHECK-NEXT: Tangent _t0; +// CHECK-NEXT: _t0 = t; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: double _grad0 = 0.; // CHECK-NEXT: double _grad1 = 0.; -// CHECK-NEXT: _t2.someMemFn2_pullback(_t0, _t1, 1, &(* _d_t), &_grad0, &_grad1); +// CHECK-NEXT: _t0.someMemFn2_pullback(i, i, 1, &(* _d_t), &_grad0, &_grad1); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: * _d_i += _r0; // CHECK-NEXT: double _r1 = _grad1; @@ -345,8 +302,11 @@ double fn6(dcomplex c, double i) { return res; } // CHECK: void real_pullback({{.*}} [[__val:.*]], clad::array_ref > _d_this, clad::array_ref<{{.*}}> [[_d___val:[a-zA-Z_]*]]){{.*}} { +// CHECK-NEXT: double _t0; +// CHECK-NEXT: _t0 ={{( __real)?}} this->[[_M_value:.*]]; // CHECK-NEXT: {{(__real)?}} this->[[_M_value:.*]] = [[__val]]; // CHECK-NEXT: { +// CHECK-NEXT: {{(__real)?}} this->[[_M_value:.*]] = _t0; // CHECK-NEXT: double _r_d0 ={{( __real)?}} (* _d_this).[[_M_value]]; // CHECK-NEXT: * [[_d___val]] += _r_d0; // CHECK-NEXT: {{(__real)?}} (* _d_this).[[_M_value]] -= _r_d0; @@ -366,53 +326,50 @@ double fn6(dcomplex c, double i) { // CHECK-NEXT: } // CHECK: void fn6_grad(dcomplex c, double i, clad::array_ref _d_c, clad::array_ref _d_i) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: dcomplex _t2; +// CHECK-NEXT: dcomplex _t0; +// CHECK-NEXT: dcomplex _t1; +// CHECK-NEXT: double _t2; // CHECK-NEXT: dcomplex _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: dcomplex _t5; -// CHECK-NEXT: double _t6; // CHECK-NEXT: double _d_res = 0; -// CHECK-NEXT: double _t7; -// CHECK-NEXT: dcomplex _t8; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t1 = 5 * _t0; -// CHECK-NEXT: _t2 = c; -// CHECK-NEXT: c.real(_t1); +// CHECK-NEXT: double _t4; +// CHECK-NEXT: double _t5; +// CHECK-NEXT: dcomplex _t6; +// CHECK-NEXT: _t0 = c; +// CHECK-NEXT: c.real(5 * i); +// CHECK-NEXT: _t1 = c; // CHECK-NEXT: _t3 = c; -// CHECK-NEXT: _t5 = c; -// CHECK-NEXT: _t4 = c.imag(); -// CHECK-NEXT: _t6 = i; -// CHECK-NEXT: double res = c.real() + 3 * _t4 + 6 * _t6; -// CHECK-NEXT: _t8 = c; -// CHECK-NEXT: _t7 = c.real(); -// CHECK-NEXT: res += 4 * _t7; +// CHECK-NEXT: _t2 = c.imag(); +// CHECK-NEXT: double res = c.real() + 3 * _t2 + 6 * i; +// CHECK-NEXT: _t4 = res; +// CHECK-NEXT: _t6 = c; +// CHECK-NEXT: _t5 = c.real(); +// CHECK-NEXT: res += 4 * _t5; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: { +// CHECK-NEXT: res = _t4; // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; -// CHECK-NEXT: double _r7 = _r_d0 * _t7; +// CHECK-NEXT: double _r7 = _r_d0 * _t5; // CHECK-NEXT: double _r8 = 4 * _r_d0; -// CHECK-NEXT: _t8.real_pullback(_r8, &(* _d_c)); +// CHECK-NEXT: _t6.real_pullback(_r8, &(* _d_c)); // CHECK-NEXT: _d_res -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: _t3.real_pullback(_d_res, &(* _d_c)); -// CHECK-NEXT: double _r3 = _d_res * _t4; +// CHECK-NEXT: _t1.real_pullback(_d_res, &(* _d_c)); +// CHECK-NEXT: double _r3 = _d_res * _t2; // CHECK-NEXT: double _r4 = 3 * _d_res; -// CHECK-NEXT: _t5.imag_pullback(_r4, &(* _d_c)); -// CHECK-NEXT: double _r5 = _d_res * _t6; +// CHECK-NEXT: _t3.imag_pullback(_r4, &(* _d_c)); +// CHECK-NEXT: double _r5 = _d_res * i; // CHECK-NEXT: double _r6 = 6 * _d_res; // CHECK-NEXT: * _d_i += _r6; // CHECK-NEXT: } // CHECK-NEXT: { // CHECK-NEXT: {{.*}} _grad0 = 0.; -// CHECK-NEXT: _t2.real_pullback(_t1, &(* _d_c), &_grad0); +// CHECK-NEXT: _t0.real_pullback(5 * i, &(* _d_c), &_grad0); // CHECK-NEXT: double _r0 = _grad0; -// CHECK-NEXT: double _r1 = _r0 * _t0; +// CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: double _r2 = 5 * _r0; // CHECK-NEXT: * _d_i += _r2; // CHECK-NEXT: } @@ -427,31 +384,29 @@ double fn7(dcomplex c1, dcomplex c2) { // CHECK-NEXT: dcomplex _t0; // CHECK-NEXT: double _t1; // CHECK-NEXT: dcomplex _t2; -// CHECK-NEXT: double _t3; +// CHECK-NEXT: dcomplex _t3; // CHECK-NEXT: dcomplex _t4; -// CHECK-NEXT: dcomplex _t5; -// CHECK-NEXT: double _t6; -// CHECK-NEXT: dcomplex _t7; +// CHECK-NEXT: double _t5; +// CHECK-NEXT: dcomplex _t6; // CHECK-NEXT: _t0 = c2; // CHECK-NEXT: _t2 = c2; // CHECK-NEXT: _t1 = c2.real(); -// CHECK-NEXT: _t3 = c2.imag() + 5 * _t1; +// CHECK-NEXT: _t3 = c1; +// CHECK-NEXT: c1.real(c2.imag() + 5 * _t1); // CHECK-NEXT: _t4 = c1; -// CHECK-NEXT: c1.real(_t3); -// CHECK-NEXT: _t5 = c1; -// CHECK-NEXT: _t7 = c1; -// CHECK-NEXT: _t6 = c1.imag(); +// CHECK-NEXT: _t6 = c1; +// CHECK-NEXT: _t5 = c1.imag(); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: _t5.real_pullback(1, &(* _d_c1)); -// CHECK-NEXT: double _r3 = 1 * _t6; +// CHECK-NEXT: _t4.real_pullback(1, &(* _d_c1)); +// CHECK-NEXT: double _r3 = 1 * _t5; // CHECK-NEXT: double _r4 = 3 * 1; -// CHECK-NEXT: _t7.imag_pullback(_r4, &(* _d_c1)); +// CHECK-NEXT: _t6.imag_pullback(_r4, &(* _d_c1)); // CHECK-NEXT: } // CHECK-NEXT: { // CHECK-NEXT: {{.*}} _grad0 = 0.; -// CHECK-NEXT: _t4.real_pullback(_t3, &(* _d_c1), &_grad0); +// CHECK-NEXT: _t3.real_pullback(c2.imag() + 5 * _t1, &(* _d_c1), &_grad0); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: _t0.imag_pullback(_r0, &(* _d_c2)); // CHECK-NEXT: double _r1 = _r0 * _t1; @@ -468,39 +423,40 @@ double fn8(Tangent t, dcomplex c) { // CHECK: void updateTo_pullback(double d, clad::array_ref _d_this, clad::array_ref _d_d) { // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: clad::tape _t1 = {}; +// CHECK-NEXT: clad::tape _t1 = {}; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: for (int i = 0; i < 5; ++i) { // CHECK-NEXT: _t0++; -// CHECK-NEXT: this->data[clad::push(_t1, i)] = d; +// CHECK-NEXT: clad::push(_t1, this->data[i]); +// CHECK-NEXT: this->data[i] = d; // CHECK-NEXT: } // CHECK-NEXT: for (; _t0; _t0--) { -// CHECK-NEXT: int _t2 = clad::pop(_t1); -// CHECK-NEXT: double _r_d0 = (* _d_this).data[_t2]; +// CHECK-NEXT: --i; +// CHECK-NEXT: this->data[i] = clad::pop(_t1); +// CHECK-NEXT: double _r_d0 = (* _d_this).data[i]; // CHECK-NEXT: * _d_d += _r_d0; -// CHECK-NEXT: (* _d_this).data[_t2] -= _r_d0; +// CHECK-NEXT: (* _d_this).data[i] -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: void fn8_grad(Tangent t, dcomplex c, clad::array_ref _d_t, clad::array_ref _d_c) { // CHECK-NEXT: dcomplex _t0; -// CHECK-NEXT: double _t1; +// CHECK-NEXT: Tangent _t1; // CHECK-NEXT: Tangent _t2; -// CHECK-NEXT: Tangent _t3; // CHECK-NEXT: _t0 = c; -// CHECK-NEXT: _t1 = c.real(); +// CHECK-NEXT: _t1 = t; +// CHECK-NEXT: t.updateTo(c.real()); // CHECK-NEXT: _t2 = t; -// CHECK-NEXT: t.updateTo(_t1); -// CHECK-NEXT: _t3 = t; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: sum_pullback(_t3, 1, &(* _d_t)); +// CHECK-NEXT: t = _t2; +// CHECK-NEXT: sum_pullback(_t2, 1, &(* _d_t)); // CHECK-NEXT: Tangent _r1 = (* _d_t); // CHECK-NEXT: } // CHECK-NEXT: { // CHECK-NEXT: double _grad0 = 0.; -// CHECK-NEXT: _t2.updateTo_pullback(_t1, &(* _d_t), &_grad0); +// CHECK-NEXT: _t1.updateTo_pullback(c.real(), &(* _d_t), &_grad0); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: _t0.real_pullback(_r0, &(* _d_c)); // CHECK-NEXT: } @@ -519,39 +475,47 @@ double fn9(Tangent t, dcomplex c) { // CHECK-NEXT: double _d_res = 0; // CHECK-NEXT: unsigned long _t0; // CHECK-NEXT: int _d_i = 0; -// CHECK-NEXT: clad::tape _t1 = {}; -// CHECK-NEXT: clad::tape _t2 = {}; -// CHECK-NEXT: clad::tape _t3 = {}; -// CHECK-NEXT: Tangent _t4; +// CHECK-NEXT: clad::tape _t1 = {}; +// CHECK-NEXT: clad::tape _t2 = {}; +// CHECK-NEXT: clad::tape _t3 = {}; +// CHECK-NEXT: clad::tape _t4 = {}; +// CHECK-NEXT: double _t5; +// CHECK-NEXT: Tangent _t6; // CHECK-NEXT: double res = 0; // CHECK-NEXT: _t0 = 0; // CHECK-NEXT: for (int i = 0; i < 5; ++i) { // CHECK-NEXT: _t0++; -// CHECK-NEXT: clad::push(_t1, c); -// CHECK-NEXT: clad::push(_t3, c); -// CHECK-NEXT: res += c.real() + 2 * clad::push(_t2, c.imag()); +// CHECK-NEXT: clad::push(_t1, res); +// CHECK-NEXT: clad::push(_t2, c); +// CHECK-NEXT: clad::push(_t4, c); +// CHECK-NEXT: res += c.real() + 2 * clad::push(_t3, c.imag()); // CHECK-NEXT: } -// CHECK-NEXT: _t4 = t; +// CHECK-NEXT: _t5 = res; +// CHECK-NEXT: _t6 = t; // CHECK-NEXT: res += sum(t); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d_res += 1; // CHECK-NEXT: { +// CHECK-NEXT: res = _t5; // CHECK-NEXT: double _r_d1 = _d_res; // CHECK-NEXT: _d_res += _r_d1; -// CHECK-NEXT: sum_pullback(_t4, _r_d1, &(* _d_t)); +// CHECK-NEXT: t = _t6; +// CHECK-NEXT: sum_pullback(_t6, _r_d1, &(* _d_t)); // CHECK-NEXT: Tangent _r4 = (* _d_t); // CHECK-NEXT: _d_res -= _r_d1; // CHECK-NEXT: } // CHECK-NEXT: for (; _t0; _t0--) { +// CHECK-NEXT: --i; // CHECK-NEXT: { +// CHECK-NEXT: res = clad::pop(_t1); // CHECK-NEXT: double _r_d0 = _d_res; // CHECK-NEXT: _d_res += _r_d0; -// CHECK-NEXT: std{{(::__1)?}}::complex _r0 = clad::pop(_t1); +// CHECK-NEXT: std{{(::__1)?}}::complex _r0 = clad::pop(_t2); // CHECK-NEXT: _r0.real_pullback(_r_d0, &(* _d_c)); -// CHECK-NEXT: double _r1 = _r_d0 * clad::pop(_t2); +// CHECK-NEXT: double _r1 = _r_d0 * clad::pop(_t3); // CHECK-NEXT: double _r2 = 2 * _r_d0; -// CHECK-NEXT: std{{(::__1)?}}::complex _r3 = clad::pop(_t3); +// CHECK-NEXT: std{{(::__1)?}}::complex _r3 = clad::pop(_t4); // CHECK-NEXT: _r3.imag_pullback(_r2, &(* _d_c)); // CHECK-NEXT: _d_res -= _r_d0; // CHECK-NEXT: } diff --git a/test/Gradient/constexprTest.C b/test/Gradient/constexprTest.C index 72c9a46cb..c874681da 100644 --- a/test/Gradient/constexprTest.C +++ b/test/Gradient/constexprTest.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oconstexprTest.out | FileCheck %s // RUN: ./constexprTest.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oconstexprTest.out +// RUN: ./constexprTest.out | FileCheck -check-prefix=CHECK-EXEC %s #include "clad/Differentiator/Differentiator.h" @@ -11,29 +13,21 @@ constexpr double mul (double a, double b, double c) { } //CHECK: constexpr void mul_grad(double a, double b, double c, clad::array_ref _d_a, clad::array_ref _d_b, clad::array_ref _d_c) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; //CHECK-NEXT: double _d_result = 0; -//CHECK-NEXT: _t2 = a; -//CHECK-NEXT: _t1 = b; -//CHECK-NEXT: _t3 = _t2 * _t1; -//CHECK-NEXT: _t0 = c; -//CHECK-NEXT: double result = _t3 * _t0; +//CHECK-NEXT: double result = a * b * c; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_result += 1; //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_result * _t0; -//CHECK-NEXT: double _r1 = _r0 * _t1; +//CHECK-NEXT: double _r0 = _d_result * c; +//CHECK-NEXT: double _r1 = _r0 * b; //CHECK-NEXT: * _d_a += _r1; -//CHECK-NEXT: double _r2 = _t2 * _r0; +//CHECK-NEXT: double _r2 = a * _r0; //CHECK-NEXT: * _d_b += _r2; -//CHECK-NEXT: double _r3 = _t3 * _d_result; +//CHECK-NEXT: double _r3 = a * b * _d_result; //CHECK-NEXT: * _d_c += _r3; //CHECK-NEXT: } -//CHECK-NEXT:} +//CHECK-NEXT: } constexpr double fn( double a, double b, double c) { double val = 98.00; @@ -44,34 +38,24 @@ constexpr double fn( double a, double b, double c) { //CHECK: constexpr void fn_grad(double a, double b, double c, clad::array_ref _d_a, clad::array_ref _d_b, clad::array_ref _d_c) { //CHECK-NEXT: double _d_val = 0; //CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; //CHECK-NEXT: double _d_result = 0; //CHECK-NEXT: double val = 98.; -//CHECK-NEXT: _t3 = a; -//CHECK-NEXT: _t2 = b; -//CHECK-NEXT: _t4 = _t3 * _t2; -//CHECK-NEXT: _t1 = c; -//CHECK-NEXT: _t5 = _t4 / _t1; -//CHECK-NEXT: _t0 = (a + b); -//CHECK-NEXT: double result = _t5 * _t0 * 100 + c; +//CHECK-NEXT: _t0 = c; +//CHECK-NEXT: double result = a * b / _t0 * (a + b) * 100 + c; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: _d_result += 1; //CHECK-NEXT: { //CHECK-NEXT: double _r0 = _d_result * 100; -//CHECK-NEXT: double _r1 = _r0 * _t0; -//CHECK-NEXT: double _r2 = _r1 / _t1; -//CHECK-NEXT: double _r3 = _r2 * _t2; +//CHECK-NEXT: double _r1 = _r0 * (a + b); +//CHECK-NEXT: double _r2 = _r1 / _t0; +//CHECK-NEXT: double _r3 = _r2 * b; //CHECK-NEXT: * _d_a += _r3; -//CHECK-NEXT: double _r4 = _t3 * _r2; +//CHECK-NEXT: double _r4 = a * _r2; //CHECK-NEXT: * _d_b += _r4; -//CHECK-NEXT: double _r5 = _r1 * -_t4 / (_t1 * _t1); +//CHECK-NEXT: double _r5 = _r1 * -a * b / (_t0 * _t0); //CHECK-NEXT: * _d_c += _r5; -//CHECK-NEXT: double _r6 = _t5 * _r0; +//CHECK-NEXT: double _r6 = a * b / _t0 * _r0; //CHECK-NEXT: * _d_a += _r6; //CHECK-NEXT: * _d_b += _r6; //CHECK-NEXT: * _d_c += _d_result; diff --git a/test/Hessian/Arrays.C b/test/Hessian/Arrays.C index 592917daf..36182ce7d 100644 --- a/test/Hessian/Arrays.C +++ b/test/Hessian/Arrays.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oArrays.out 2>&1 | FileCheck %s // RUN: ./Arrays.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oArrays.out +// RUN: ./Arrays.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} diff --git a/test/Hessian/BuiltinDerivatives.C b/test/Hessian/BuiltinDerivatives.C index d6a401e94..0615d0000 100644 --- a/test/Hessian/BuiltinDerivatives.C +++ b/test/Hessian/BuiltinDerivatives.C @@ -1,5 +1,8 @@ // RUN: %cladclang %s -I%S/../../include -oHessianBuiltinDerivatives.out 2>&1 | FileCheck %s // RUN: ./HessianBuiltinDerivatives.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oHessianBuiltinDerivatives.out +// RUN: ./HessianBuiltinDerivatives.out | FileCheck -check-prefix=CHECK-EXEC %s + //CHECK-NOT: {{.*error|warning|note:.*}} @@ -18,68 +21,44 @@ float f1(float x) { // CHECK-NEXT: } // CHECK: void sin_pushforward_pullback(float x, float d_x, ValueAndPushforward _d_y, clad::array_ref _d_x, clad::array_ref _d_d_x) { -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; -// CHECK-NEXT: float _t2; -// CHECK-NEXT: float _t3; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t2 = x; -// CHECK-NEXT: _t3 = ::std::cos(_t2); -// CHECK-NEXT: _t1 = d_x; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: float _r0 = _d_y.value * clad::custom_derivatives{{(::std)?}}::sin_pushforward(_t0, 1.F).pushforward; +// CHECK-NEXT: float _r0 = _d_y.value * clad::custom_derivatives{{(::std)?}}::sin_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r0; -// CHECK-NEXT: float _r1 = _d_y.pushforward * _t1; -// CHECK-NEXT: float _r2 = _r1 * clad::custom_derivatives{{(::std)?}}::cos_pushforward(_t2, 1.F).pushforward; +// CHECK-NEXT: float _r1 = _d_y.pushforward * d_x; +// CHECK-NEXT: float _r2 = _r1 * clad::custom_derivatives{{(::std)?}}::cos_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r2; -// CHECK-NEXT: float _r3 = _t3 * _d_y.pushforward; +// CHECK-NEXT: float _r3 = ::std::cos(x) * _d_y.pushforward; // CHECK-NEXT: * _d_d_x += _r3; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: void cos_pushforward_pullback(float x, float d_x, ValueAndPushforward _d_y, clad::array_ref _d_x, clad::array_ref _d_d_x) { // CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; -// CHECK-NEXT: float _t2; -// CHECK-NEXT: float _t3; -// CHECK-NEXT: float _t4; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t3 = x; -// CHECK-NEXT: _t2 = ::std::sin(_t3); -// CHECK-NEXT: _t4 = -1 * _t2; -// CHECK-NEXT: _t1 = d_x; +// CHECK-NEXT: _t0 = ::std::sin(x); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: float _r0 = _d_y.value * clad::custom_derivatives{{(::std)?}}::cos_pushforward(_t0, 1.F).pushforward; +// CHECK-NEXT: float _r0 = _d_y.value * clad::custom_derivatives{{(::std)?}}::cos_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r0; -// CHECK-NEXT: float _r1 = _d_y.pushforward * _t1; -// CHECK-NEXT: float _r2 = _r1 * _t2; +// CHECK-NEXT: float _r1 = _d_y.pushforward * d_x; +// CHECK-NEXT: float _r2 = _r1 * _t0; // CHECK-NEXT: float _r3 = -1 * _r1; -// CHECK-NEXT: float _r4 = _r3 * clad::custom_derivatives{{(::std)?}}::sin_pushforward(_t3, 1.F).pushforward; +// CHECK-NEXT: float _r4 = _r3 * clad::custom_derivatives{{(::std)?}}::sin_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r4; -// CHECK-NEXT: float _r5 = _t4 * _d_y.pushforward; +// CHECK-NEXT: float _r5 = -1 * _t0 * _d_y.pushforward; // CHECK-NEXT: * _d_d_x += _r5; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: void f1_darg0_grad(float x, clad::array_ref _d_x) { // CHECK-NEXT: float _d__d_x = 0; -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; // CHECK-NEXT: ValueAndPushforward _d__t0 = {}; -// CHECK-NEXT: float _t2; -// CHECK-NEXT: float _t3; // CHECK-NEXT: ValueAndPushforward _d__t1 = {}; // CHECK-NEXT: float _d_x0 = 1; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = _d_x0; -// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::sin_pushforward(_t0, _t1); -// CHECK-NEXT: _t2 = x; -// CHECK-NEXT: _t3 = _d_x0; -// CHECK-NEXT: ValueAndPushforward _t10 = clad::custom_derivatives{{(::std)?}}::cos_pushforward(_t2, _t3); +// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::sin_pushforward(x, _d_x0); +// CHECK-NEXT: ValueAndPushforward _t10 = clad::custom_derivatives{{(::std)?}}::cos_pushforward(x, _d_x0); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { @@ -89,7 +68,7 @@ float f1(float x) { // CHECK-NEXT: { // CHECK-NEXT: float _grad2 = 0.F; // CHECK-NEXT: float _grad3 = 0.F; -// CHECK-NEXT: cos_pushforward_pullback(_t2, _t3, _d__t1, &_grad2, &_grad3); +// CHECK-NEXT: cos_pushforward_pullback(x, _d_x0, _d__t1, &_grad2, &_grad3); // CHECK-NEXT: float _r2 = _grad2; // CHECK-NEXT: * _d_x += _r2; // CHECK-NEXT: float _r3 = _grad3; @@ -98,7 +77,7 @@ float f1(float x) { // CHECK-NEXT: { // CHECK-NEXT: float _grad0 = 0.F; // CHECK-NEXT: float _grad1 = 0.F; -// CHECK-NEXT: sin_pushforward_pullback(_t0, _t1, _d__t0, &_grad0, &_grad1); +// CHECK-NEXT: sin_pushforward_pullback(x, _d_x0, _d__t0, &_grad0, &_grad1); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: float _r1 = _grad1; @@ -121,43 +100,31 @@ float f2(float x) { // CHECK-NEXT: } // CHECK: void exp_pushforward_pullback(float x, float d_x, ValueAndPushforward _d_y, clad::array_ref _d_x, clad::array_ref _d_d_x) { -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; -// CHECK-NEXT: float _t2; -// CHECK-NEXT: float _t3; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t2 = x; -// CHECK-NEXT: _t3 = ::std::exp(_t2); -// CHECK-NEXT: _t1 = d_x; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: float _r0 = _d_y.value * clad::custom_derivatives{{(::std)?}}::exp_pushforward(_t0, 1.F).pushforward; +// CHECK-NEXT: float _r0 = _d_y.value * clad::custom_derivatives{{(::std)?}}::exp_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r0; -// CHECK-NEXT: float _r1 = _d_y.pushforward * _t1; -// CHECK-NEXT: float _r2 = _r1 * clad::custom_derivatives{{(::std)?}}::exp_pushforward(_t2, 1.F).pushforward; +// CHECK-NEXT: float _r1 = _d_y.pushforward * d_x; +// CHECK-NEXT: float _r2 = _r1 * clad::custom_derivatives{{(::std)?}}::exp_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r2; -// CHECK-NEXT: float _r3 = _t3 * _d_y.pushforward; +// CHECK-NEXT: float _r3 = ::std::exp(x) * _d_y.pushforward; // CHECK-NEXT: * _d_d_x += _r3; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: void f2_darg0_grad(float x, clad::array_ref _d_x) { // CHECK-NEXT: float _d__d_x = 0; -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; // CHECK-NEXT: ValueAndPushforward _d__t0 = {}; // CHECK-NEXT: float _d_x0 = 1; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = _d_x0; -// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::exp_pushforward(_t0, _t1); +// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::exp_pushforward(x, _d_x0); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d__t0.pushforward += 1; // CHECK-NEXT: { // CHECK-NEXT: float _grad0 = 0.F; // CHECK-NEXT: float _grad1 = 0.F; -// CHECK-NEXT: exp_pushforward_pullback(_t0, _t1, _d__t0, &_grad0, &_grad1); +// CHECK-NEXT: exp_pushforward_pullback(x, _d_x0, _d__t0, &_grad0, &_grad1); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: float _r1 = _grad1; @@ -181,44 +148,34 @@ float f3(float x) { // CHECK-NEXT: } // CHECK: void log_pushforward_pullback(float x, float d_x, ValueAndPushforward _d_y, clad::array_ref _d_x, clad::array_ref _d_d_x) { -// CHECK-NEXT: float _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; +// CHECK-NEXT: double _t0; // CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t2 = x; -// CHECK-NEXT: _t3 = (1. / _t2); -// CHECK-NEXT: _t1 = d_x; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: float _r0 = _d_y.value * clad::custom_derivatives{{(::std)?}}::log_pushforward(_t0, 1.F).pushforward; +// CHECK-NEXT: float _r0 = _d_y.value * clad::custom_derivatives{{(::std)?}}::log_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r0; -// CHECK-NEXT: double _r1 = _d_y.pushforward * _t1; -// CHECK-NEXT: double _r2 = _r1 / _t2; -// CHECK-NEXT: double _r3 = _r1 * -1. / (_t2 * _t2); +// CHECK-NEXT: double _r1 = _d_y.pushforward * d_x; +// CHECK-NEXT: double _r2 = _r1 / _t0; +// CHECK-NEXT: double _r3 = _r1 * -1. / (_t0 * _t0); // CHECK-NEXT: * _d_x += _r3; -// CHECK-NEXT: double _r4 = _t3 * _d_y.pushforward; +// CHECK-NEXT: double _r4 = (1. / _t0) * _d_y.pushforward; // CHECK-NEXT: * _d_d_x += _r4; // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: void f3_darg0_grad(float x, clad::array_ref _d_x) { // CHECK-NEXT: float _d__d_x = 0; -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; // CHECK-NEXT: ValueAndPushforward _d__t0 = {}; // CHECK-NEXT: float _d_x0 = 1; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = _d_x0; -// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::log_pushforward(_t0, _t1); +// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::log_pushforward(x, _d_x0); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d__t0.pushforward += 1; // CHECK-NEXT: { // CHECK-NEXT: float _grad0 = 0.F; // CHECK-NEXT: float _grad1 = 0.F; -// CHECK-NEXT: log_pushforward_pullback(_t0, _t1, _d__t0, &_grad0, &_grad1); +// CHECK-NEXT: log_pushforward_pullback(x, _d_x0, _d__t0, &_grad0, &_grad1); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: float _r1 = _grad1; @@ -242,44 +199,20 @@ float f4(float x) { // CHECK-NEXT: } // CHECK: void pow_pushforward_pullback(float x, float exponent, float d_x, float d_exponent, ValueAndPushforward _d_y, clad::array_ref _d_x, clad::array_ref _d_exponent, clad::array_ref _d_d_x, clad::array_ref _d_d_exponent) { -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; // CHECK-NEXT: float _d_val = 0; -// CHECK-NEXT: float _t2; -// CHECK-NEXT: float _t3; -// CHECK-NEXT: float _t4; -// CHECK-NEXT: float _t5; -// CHECK-NEXT: float _t6; -// CHECK-NEXT: float _t7; +// CHECK-NEXT: float _t0; // CHECK-NEXT: float _d_derivative = 0; // CHECK-NEXT: float _cond0; -// CHECK-NEXT: float _t8; -// CHECK-NEXT: float _t9; -// CHECK-NEXT: float _t10; -// CHECK-NEXT: float _t11; -// CHECK-NEXT: float _t12; -// CHECK-NEXT: float _t13; -// CHECK-NEXT: float _t14; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = exponent; -// CHECK-NEXT: float val = ::std::pow(_t0, _t1); -// CHECK-NEXT: _t4 = exponent; -// CHECK-NEXT: _t5 = x; -// CHECK-NEXT: _t6 = exponent - 1; -// CHECK-NEXT: _t3 = ::std::pow(_t5, _t6); -// CHECK-NEXT: _t7 = (_t4 * _t3); -// CHECK-NEXT: _t2 = d_x; -// CHECK-NEXT: float derivative = _t7 * _t2; +// CHECK-NEXT: float _t1; +// CHECK-NEXT: float _t2; +// CHECK-NEXT: float val = ::std::pow(x, exponent); +// CHECK-NEXT: _t0 = ::std::pow(x, exponent - 1); +// CHECK-NEXT: float derivative = (exponent * _t0) * d_x; // CHECK-NEXT: _cond0 = d_exponent; // CHECK-NEXT: if (_cond0) { -// CHECK-NEXT: _t10 = x; -// CHECK-NEXT: _t11 = exponent; -// CHECK-NEXT: _t12 = ::std::pow(_t10, _t11); -// CHECK-NEXT: _t13 = x; -// CHECK-NEXT: _t9 = ::std::log(_t13); -// CHECK-NEXT: _t14 = (_t12 * _t9); -// CHECK-NEXT: _t8 = d_exponent; -// CHECK-NEXT: derivative += _t14 * _t8; +// CHECK-NEXT: _t1 = derivative; +// CHECK-NEXT: _t2 = ::std::log(x); +// CHECK-NEXT: derivative += (::std::pow(x, exponent) * _t2) * d_exponent; // CHECK-NEXT: } // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: @@ -288,43 +221,44 @@ float f4(float x) { // CHECK-NEXT: _d_derivative += _d_y.pushforward; // CHECK-NEXT: } // CHECK-NEXT: if (_cond0) { +// CHECK-NEXT: derivative = _t1; // CHECK-NEXT: float _r_d0 = _d_derivative; // CHECK-NEXT: _d_derivative += _r_d0; -// CHECK-NEXT: float _r8 = _r_d0 * _t8; -// CHECK-NEXT: float _r9 = _r8 * _t9; +// CHECK-NEXT: float _r8 = _r_d0 * d_exponent; +// CHECK-NEXT: float _r9 = _r8 * _t2; // CHECK-NEXT: float _grad4 = 0.F; // CHECK-NEXT: float _grad5 = 0.F; -// CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(_t10, _t11, _r9, &_grad4, &_grad5); +// CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(x, exponent, _r9, &_grad4, &_grad5); // CHECK-NEXT: float _r10 = _grad4; // CHECK-NEXT: * _d_x += _r10; // CHECK-NEXT: float _r11 = _grad5; // CHECK-NEXT: * _d_exponent += _r11; -// CHECK-NEXT: float _r12 = _t12 * _r8; -// CHECK-NEXT: float _r13 = _r12 * clad::custom_derivatives{{(::std)?}}::log_pushforward(_t13, 1.F).pushforward; +// CHECK-NEXT: float _r12 = ::std::pow(x, exponent) * _r8; +// CHECK-NEXT: float _r13 = _r12 * clad::custom_derivatives{{(::std)?}}::log_pushforward(x, 1.F).pushforward; // CHECK-NEXT: * _d_x += _r13; -// CHECK-NEXT: float _r14 = _t14 * _r_d0; +// CHECK-NEXT: float _r14 = (::std::pow(x, exponent) * _t2) * _r_d0; // CHECK-NEXT: * _d_d_exponent += _r14; // CHECK-NEXT: _d_derivative -= _r_d0; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: float _r2 = _d_derivative * _t2; -// CHECK-NEXT: float _r3 = _r2 * _t3; +// CHECK-NEXT: float _r2 = _d_derivative * d_x; +// CHECK-NEXT: float _r3 = _r2 * _t0; // CHECK-NEXT: * _d_exponent += _r3; -// CHECK-NEXT: float _r4 = _t4 * _r2; +// CHECK-NEXT: float _r4 = exponent * _r2; // CHECK-NEXT: float _grad2 = 0.F; // CHECK-NEXT: float _grad3 = 0.F; -// CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(_t5, _t6, _r4, &_grad2, &_grad3); +// CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(x, exponent - 1, _r4, &_grad2, &_grad3); // CHECK-NEXT: float _r5 = _grad2; // CHECK-NEXT: * _d_x += _r5; // CHECK-NEXT: float _r6 = _grad3; // CHECK-NEXT: * _d_exponent += _r6; -// CHECK-NEXT: float _r7 = _t7 * _d_derivative; +// CHECK-NEXT: float _r7 = (exponent * _t0) * _d_derivative; // CHECK-NEXT: * _d_d_x += _r7; // CHECK-NEXT: } // CHECK-NEXT: { // CHECK-NEXT: float _grad0 = 0.F; // CHECK-NEXT: float _grad1 = 0.F; -// CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(_t0, _t1, _d_val, &_grad0, &_grad1); +// CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(x, exponent, _d_val, &_grad0, &_grad1); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: float _r1 = _grad1; @@ -334,13 +268,9 @@ float f4(float x) { // CHECK: void f4_darg0_grad(float x, clad::array_ref _d_x) { // CHECK-NEXT: float _d__d_x = 0; -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; // CHECK-NEXT: ValueAndPushforward _d__t0 = {}; // CHECK-NEXT: float _d_x0 = 1; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = _d_x0; -// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(_t0, 4.F, _t1, 0.F); +// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(x, 4.F, _d_x0, 0.F); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d__t0.pushforward += 1; @@ -349,7 +279,7 @@ float f4(float x) { // CHECK-NEXT: float _grad1 = 0.F; // CHECK-NEXT: float _grad2 = 0.F; // CHECK-NEXT: float _grad3 = 0.F; -// CHECK-NEXT: pow_pushforward_pullback(_t0, 4.F, _t1, 0.F, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); +// CHECK-NEXT: pow_pushforward_pullback(x, 4.F, _d_x0, 0.F, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: float _r1 = _grad1; @@ -376,13 +306,9 @@ float f5(float x) { // CHECK: void f5_darg0_grad(float x, clad::array_ref _d_x) { // CHECK-NEXT: float _d__d_x = 0; -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; // CHECK-NEXT: ValueAndPushforward _d__t0 = {}; // CHECK-NEXT: float _d_x0 = 1; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = _d_x0; -// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(2.F, _t0, 0.F, _t1); +// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(2.F, x, 0.F, _d_x0); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d__t0.pushforward += 1; @@ -391,7 +317,7 @@ float f5(float x) { // CHECK-NEXT: float _grad1 = 0.F; // CHECK-NEXT: float _grad2 = 0.F; // CHECK-NEXT: float _grad3 = 0.F; -// CHECK-NEXT: pow_pushforward_pullback(2.F, _t0, 0.F, _t1, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); +// CHECK-NEXT: pow_pushforward_pullback(2.F, x, 0.F, _d_x0, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: float _r1 = _grad1; // CHECK-NEXT: * _d_x += _r1; @@ -420,18 +346,10 @@ float f6(float x, float y) { // CHECK: void f6_darg0_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y) { // CHECK-NEXT: float _d__d_x = 0; // CHECK-NEXT: float _d__d_y = 0; -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; -// CHECK-NEXT: float _t2; -// CHECK-NEXT: float _t3; // CHECK-NEXT: ValueAndPushforward _d__t0 = {}; // CHECK-NEXT: float _d_x0 = 1; // CHECK-NEXT: float _d_y0 = 0; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = y; -// CHECK-NEXT: _t2 = _d_x0; -// CHECK-NEXT: _t3 = _d_y0; -// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(_t0, _t1, _t2, _t3); +// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(x, y, _d_x0, _d_y0); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d__t0.pushforward += 1; @@ -440,7 +358,7 @@ float f6(float x, float y) { // CHECK-NEXT: float _grad1 = 0.F; // CHECK-NEXT: float _grad2 = 0.F; // CHECK-NEXT: float _grad3 = 0.F; -// CHECK-NEXT: pow_pushforward_pullback(_t0, _t1, _t2, _t3, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); +// CHECK-NEXT: pow_pushforward_pullback(x, y, _d_x0, _d_y0, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: float _r1 = _grad1; @@ -462,18 +380,10 @@ float f6(float x, float y) { // CHECK: void f6_darg1_grad(float x, float y, clad::array_ref _d_x, clad::array_ref _d_y) { // CHECK-NEXT: float _d__d_x = 0; // CHECK-NEXT: float _d__d_y = 0; -// CHECK-NEXT: float _t0; -// CHECK-NEXT: float _t1; -// CHECK-NEXT: float _t2; -// CHECK-NEXT: float _t3; // CHECK-NEXT: ValueAndPushforward _d__t0 = {}; // CHECK-NEXT: float _d_x0 = 0; // CHECK-NEXT: float _d_y0 = 1; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = y; -// CHECK-NEXT: _t2 = _d_x0; -// CHECK-NEXT: _t3 = _d_y0; -// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(_t0, _t1, _t2, _t3); +// CHECK-NEXT: ValueAndPushforward _t00 = clad::custom_derivatives{{(::std)?}}::pow_pushforward(x, y, _d_x0, _d_y0); // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: _d__t0.pushforward += 1; @@ -482,7 +392,7 @@ float f6(float x, float y) { // CHECK-NEXT: float _grad1 = 0.F; // CHECK-NEXT: float _grad2 = 0.F; // CHECK-NEXT: float _grad3 = 0.F; -// CHECK-NEXT: pow_pushforward_pullback(_t0, _t1, _t2, _t3, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); +// CHECK-NEXT: pow_pushforward_pullback(x, y, _d_x0, _d_y0, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); // CHECK-NEXT: float _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: float _r1 = _grad1; diff --git a/test/Hessian/Functors.C b/test/Hessian/Functors.C index eb1fbe054..c5e3a71a7 100644 --- a/test/Hessian/Functors.C +++ b/test/Hessian/Functors.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oFunctors.out 2>&1 | FileCheck %s // RUN: ./Functors.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oFunctors.out +// RUN: ./Functors.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" diff --git a/test/Hessian/Hessians.C b/test/Hessian/Hessians.C index f7249a867..c09b5d16c 100644 --- a/test/Hessian/Hessians.C +++ b/test/Hessian/Hessians.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oHessians.out 2>&1 | FileCheck %s // RUN: ./Hessians.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oHessians.out +// RUN: ./Hessians.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -13,96 +15,56 @@ void f_cubed_add1_darg0_grad(double a, double b, clad::array_ref _d_a, c //CHECK:void f_cubed_add1_darg0_grad(double a, double b, clad::array_ref _d_a, clad::array_ref _d_b) __attribute__((always_inline)) { //CHECK-NEXT: double _d__d_a = 0; //CHECK-NEXT: double _d__d_b = 0; -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; //CHECK-NEXT: double _d__t0 = 0; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; //CHECK-NEXT: double _d__t1 = 0; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: double _t9; -//CHECK-NEXT: double _t11; -//CHECK-NEXT: double _t12; -//CHECK-NEXT: double _t13; -//CHECK-NEXT: double _t14; -//CHECK-NEXT: double _t15; -//CHECK-NEXT: double _t16; -//CHECK-NEXT: double _t17; -//CHECK-NEXT: double _t18; -//CHECK-NEXT: double _t19; -//CHECK-NEXT: double _t20; //CHECK-NEXT: double _d_a0 = 1; //CHECK-NEXT: double _d_b0 = 0; -//CHECK-NEXT: _t1 = a; -//CHECK-NEXT: _t0 = a; -//CHECK-NEXT: double _t00 = _t1 * _t0; -//CHECK-NEXT: _t3 = b; -//CHECK-NEXT: _t2 = b; -//CHECK-NEXT: double _t10 = _t3 * _t2; -//CHECK-NEXT: _t6 = _d_a0; -//CHECK-NEXT: _t5 = a; -//CHECK-NEXT: _t8 = a; -//CHECK-NEXT: _t7 = _d_a0; -//CHECK-NEXT: _t9 = (_t6 * _t5 + _t8 * _t7); -//CHECK-NEXT: _t4 = a; -//CHECK-NEXT: _t12 = _t00; -//CHECK-NEXT: _t11 = _d_a0; -//CHECK-NEXT: _t15 = _d_b0; -//CHECK-NEXT: _t14 = b; -//CHECK-NEXT: _t17 = b; -//CHECK-NEXT: _t16 = _d_b0; -//CHECK-NEXT: _t18 = (_t15 * _t14 + _t17 * _t16); -//CHECK-NEXT: _t13 = b; -//CHECK-NEXT: _t20 = _t10; -//CHECK-NEXT: _t19 = _d_b0; +//CHECK-NEXT: double _t00 = a * a; +//CHECK-NEXT: double _t10 = b * b; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = 1 * _t4; -//CHECK-NEXT: double _r5 = _r4 * _t5; +//CHECK-NEXT: double _r4 = 1 * a; +//CHECK-NEXT: double _r5 = _r4 * a; //CHECK-NEXT: _d__d_a += _r5; -//CHECK-NEXT: double _r6 = _t6 * _r4; +//CHECK-NEXT: double _r6 = _d_a0 * _r4; //CHECK-NEXT: * _d_a += _r6; -//CHECK-NEXT: double _r7 = _r4 * _t7; +//CHECK-NEXT: double _r7 = _r4 * _d_a0; //CHECK-NEXT: * _d_a += _r7; -//CHECK-NEXT: double _r8 = _t8 * _r4; +//CHECK-NEXT: double _r8 = a * _r4; //CHECK-NEXT: _d__d_a += _r8; -//CHECK-NEXT: double _r9 = _t9 * 1; +//CHECK-NEXT: double _r9 = (_d_a0 * a + a * _d_a0) * 1; //CHECK-NEXT: * _d_a += _r9; -//CHECK-NEXT: double _r10 = 1 * _t11; +//CHECK-NEXT: double _r10 = 1 * _d_a0; //CHECK-NEXT: _d__t0 += _r10; -//CHECK-NEXT: double _r11 = _t12 * 1; +//CHECK-NEXT: double _r11 = _t00 * 1; //CHECK-NEXT: _d__d_a += _r11; -//CHECK-NEXT: double _r12 = 1 * _t13; -//CHECK-NEXT: double _r13 = _r12 * _t14; +//CHECK-NEXT: double _r12 = 1 * b; +//CHECK-NEXT: double _r13 = _r12 * b; //CHECK-NEXT: _d__d_b += _r13; -//CHECK-NEXT: double _r14 = _t15 * _r12; +//CHECK-NEXT: double _r14 = _d_b0 * _r12; //CHECK-NEXT: * _d_b += _r14; -//CHECK-NEXT: double _r15 = _r12 * _t16; +//CHECK-NEXT: double _r15 = _r12 * _d_b0; //CHECK-NEXT: * _d_b += _r15; -//CHECK-NEXT: double _r16 = _t17 * _r12; +//CHECK-NEXT: double _r16 = b * _r12; //CHECK-NEXT: _d__d_b += _r16; -//CHECK-NEXT: double _r17 = _t18 * 1; +//CHECK-NEXT: double _r17 = (_d_b0 * b + b * _d_b0) * 1; //CHECK-NEXT: * _d_b += _r17; -//CHECK-NEXT: double _r18 = 1 * _t19; +//CHECK-NEXT: double _r18 = 1 * _d_b0; //CHECK-NEXT: _d__t1 += _r18; -//CHECK-NEXT: double _r19 = _t20 * 1; +//CHECK-NEXT: double _r19 = _t10 * 1; //CHECK-NEXT: _d__d_b += _r19; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r2 = _d__t1 * _t2; +//CHECK-NEXT: double _r2 = _d__t1 * b; //CHECK-NEXT: * _d_b += _r2; -//CHECK-NEXT: double _r3 = _t3 * _d__t1; +//CHECK-NEXT: double _r3 = b * _d__t1; //CHECK-NEXT: * _d_b += _r3; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d__t0 * _t0; +//CHECK-NEXT: double _r0 = _d__t0 * a; //CHECK-NEXT: * _d_a += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d__t0; +//CHECK-NEXT: double _r1 = a * _d__t0; //CHECK-NEXT: * _d_a += _r1; //CHECK-NEXT: } //CHECK-NEXT:} @@ -111,96 +73,56 @@ void f_cubed_add1_darg1_grad(double a, double b, clad::array_ref _d_a, c //CHECK:void f_cubed_add1_darg1_grad(double a, double b, clad::array_ref _d_a, clad::array_ref _d_b) __attribute__((always_inline)) { //CHECK-NEXT: double _d__d_a = 0; //CHECK-NEXT: double _d__d_b = 0; -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; //CHECK-NEXT: double _d__t0 = 0; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; //CHECK-NEXT: double _d__t1 = 0; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: double _t9; -//CHECK-NEXT: double _t11; -//CHECK-NEXT: double _t12; -//CHECK-NEXT: double _t13; -//CHECK-NEXT: double _t14; -//CHECK-NEXT: double _t15; -//CHECK-NEXT: double _t16; -//CHECK-NEXT: double _t17; -//CHECK-NEXT: double _t18; -//CHECK-NEXT: double _t19; -//CHECK-NEXT: double _t20; //CHECK-NEXT: double _d_a0 = 0; //CHECK-NEXT: double _d_b0 = 1; -//CHECK-NEXT: _t1 = a; -//CHECK-NEXT: _t0 = a; -//CHECK-NEXT: double _t00 = _t1 * _t0; -//CHECK-NEXT: _t3 = b; -//CHECK-NEXT: _t2 = b; -//CHECK-NEXT: double _t10 = _t3 * _t2; -//CHECK-NEXT: _t6 = _d_a0; -//CHECK-NEXT: _t5 = a; -//CHECK-NEXT: _t8 = a; -//CHECK-NEXT: _t7 = _d_a0; -//CHECK-NEXT: _t9 = (_t6 * _t5 + _t8 * _t7); -//CHECK-NEXT: _t4 = a; -//CHECK-NEXT: _t12 = _t00; -//CHECK-NEXT: _t11 = _d_a0; -//CHECK-NEXT: _t15 = _d_b0; -//CHECK-NEXT: _t14 = b; -//CHECK-NEXT: _t17 = b; -//CHECK-NEXT: _t16 = _d_b0; -//CHECK-NEXT: _t18 = (_t15 * _t14 + _t17 * _t16); -//CHECK-NEXT: _t13 = b; -//CHECK-NEXT: _t20 = _t10; -//CHECK-NEXT: _t19 = _d_b0; +//CHECK-NEXT: double _t00 = a * a; +//CHECK-NEXT: double _t10 = b * b; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = 1 * _t4; -//CHECK-NEXT: double _r5 = _r4 * _t5; +//CHECK-NEXT: double _r4 = 1 * a; +//CHECK-NEXT: double _r5 = _r4 * a; //CHECK-NEXT: _d__d_a += _r5; -//CHECK-NEXT: double _r6 = _t6 * _r4; +//CHECK-NEXT: double _r6 = _d_a0 * _r4; //CHECK-NEXT: * _d_a += _r6; -//CHECK-NEXT: double _r7 = _r4 * _t7; +//CHECK-NEXT: double _r7 = _r4 * _d_a0; //CHECK-NEXT: * _d_a += _r7; -//CHECK-NEXT: double _r8 = _t8 * _r4; +//CHECK-NEXT: double _r8 = a * _r4; //CHECK-NEXT: _d__d_a += _r8; -//CHECK-NEXT: double _r9 = _t9 * 1; +//CHECK-NEXT: double _r9 = (_d_a0 * a + a * _d_a0) * 1; //CHECK-NEXT: * _d_a += _r9; -//CHECK-NEXT: double _r10 = 1 * _t11; +//CHECK-NEXT: double _r10 = 1 * _d_a0; //CHECK-NEXT: _d__t0 += _r10; -//CHECK-NEXT: double _r11 = _t12 * 1; +//CHECK-NEXT: double _r11 = _t00 * 1; //CHECK-NEXT: _d__d_a += _r11; -//CHECK-NEXT: double _r12 = 1 * _t13; -//CHECK-NEXT: double _r13 = _r12 * _t14; +//CHECK-NEXT: double _r12 = 1 * b; +//CHECK-NEXT: double _r13 = _r12 * b; //CHECK-NEXT: _d__d_b += _r13; -//CHECK-NEXT: double _r14 = _t15 * _r12; +//CHECK-NEXT: double _r14 = _d_b0 * _r12; //CHECK-NEXT: * _d_b += _r14; -//CHECK-NEXT: double _r15 = _r12 * _t16; +//CHECK-NEXT: double _r15 = _r12 * _d_b0; //CHECK-NEXT: * _d_b += _r15; -//CHECK-NEXT: double _r16 = _t17 * _r12; +//CHECK-NEXT: double _r16 = b * _r12; //CHECK-NEXT: _d__d_b += _r16; -//CHECK-NEXT: double _r17 = _t18 * 1; +//CHECK-NEXT: double _r17 = (_d_b0 * b + b * _d_b0) * 1; //CHECK-NEXT: * _d_b += _r17; -//CHECK-NEXT: double _r18 = 1 * _t19; +//CHECK-NEXT: double _r18 = 1 * _d_b0; //CHECK-NEXT: _d__t1 += _r18; -//CHECK-NEXT: double _r19 = _t20 * 1; +//CHECK-NEXT: double _r19 = _t10 * 1; //CHECK-NEXT: _d__d_b += _r19; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r2 = _d__t1 * _t2; +//CHECK-NEXT: double _r2 = _d__t1 * b; //CHECK-NEXT: * _d_b += _r2; -//CHECK-NEXT: double _r3 = _t3 * _d__t1; +//CHECK-NEXT: double _r3 = b * _d__t1; //CHECK-NEXT: * _d_b += _r3; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d__t0 * _t0; +//CHECK-NEXT: double _r0 = _d__t0 * a; //CHECK-NEXT: * _d_a += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d__t0; +//CHECK-NEXT: double _r1 = a * _d__t0; //CHECK-NEXT: * _d_a += _r1; //CHECK-NEXT: } //CHECK-NEXT:} diff --git a/test/Hessian/NestedFunctionCalls.C b/test/Hessian/NestedFunctionCalls.C index 7518c0aa1..6518f4313 100644 --- a/test/Hessian/NestedFunctionCalls.C +++ b/test/Hessian/NestedFunctionCalls.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oNestedFunctionCalls.out 2>&1 | FileCheck %s // RUN: ./NestedFunctionCalls.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oNestedFunctionCalls.out +// RUN: ./NestedFunctionCalls.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} @@ -29,56 +31,32 @@ double f2(double x, double y){ // CHECK-NEXT: } // CHECK: void f_pushforward_pullback(double x, double y, double _d_x, double _d_y, clad::ValueAndPushforward _d_y0, clad::array_ref _d_x, clad::array_ref _d_y, clad::array_ref _d__d_x, clad::array_ref _d__d_y) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: double _t5; -// CHECK-NEXT: double _t6; -// CHECK-NEXT: double _t7; -// CHECK-NEXT: double _t8; -// CHECK-NEXT: double _t9; -// CHECK-NEXT: double _t10; -// CHECK-NEXT: double _t11; -// CHECK-NEXT: _t1 = x; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t3 = y; -// CHECK-NEXT: _t2 = y; -// CHECK-NEXT: _t5 = _d_x; -// CHECK-NEXT: _t4 = x; -// CHECK-NEXT: _t7 = x; -// CHECK-NEXT: _t6 = _d_x; -// CHECK-NEXT: _t9 = _d_y; -// CHECK-NEXT: _t8 = y; -// CHECK-NEXT: _t11 = y; -// CHECK-NEXT: _t10 = _d_y; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = _d_y0.value * _t0; +// CHECK-NEXT: double _r0 = _d_y0.value * x; // CHECK-NEXT: * _d_x += _r0; -// CHECK-NEXT: double _r1 = _t1 * _d_y0.value; +// CHECK-NEXT: double _r1 = x * _d_y0.value; // CHECK-NEXT: * _d_x += _r1; -// CHECK-NEXT: double _r2 = _d_y0.value * _t2; +// CHECK-NEXT: double _r2 = _d_y0.value * y; // CHECK-NEXT: * _d_y += _r2; -// CHECK-NEXT: double _r3 = _t3 * _d_y0.value; +// CHECK-NEXT: double _r3 = y * _d_y0.value; // CHECK-NEXT: * _d_y += _r3; -// CHECK-NEXT: double _r4 = _d_y0.pushforward * _t4; +// CHECK-NEXT: double _r4 = _d_y0.pushforward * x; // CHECK-NEXT: * _d__d_x += _r4; -// CHECK-NEXT: double _r5 = _t5 * _d_y0.pushforward; +// CHECK-NEXT: double _r5 = _d_x * _d_y0.pushforward; // CHECK-NEXT: * _d_x += _r5; -// CHECK-NEXT: double _r6 = _d_y0.pushforward * _t6; +// CHECK-NEXT: double _r6 = _d_y0.pushforward * _d_x; // CHECK-NEXT: * _d_x += _r6; -// CHECK-NEXT: double _r7 = _t7 * _d_y0.pushforward; +// CHECK-NEXT: double _r7 = x * _d_y0.pushforward; // CHECK-NEXT: * _d__d_x += _r7; -// CHECK-NEXT: double _r8 = _d_y0.pushforward * _t8; +// CHECK-NEXT: double _r8 = _d_y0.pushforward * y; // CHECK-NEXT: * _d__d_y += _r8; -// CHECK-NEXT: double _r9 = _t9 * _d_y0.pushforward; +// CHECK-NEXT: double _r9 = _d_y * _d_y0.pushforward; // CHECK-NEXT: * _d_y += _r9; -// CHECK-NEXT: double _r10 = _d_y0.pushforward * _t10; +// CHECK-NEXT: double _r10 = _d_y0.pushforward * _d_y; // CHECK-NEXT: * _d_y += _r10; -// CHECK-NEXT: double _r11 = _t11 * _d_y0.pushforward; +// CHECK-NEXT: double _r11 = y * _d_y0.pushforward; // CHECK-NEXT: * _d__d_y += _r11; // CHECK-NEXT: } // CHECK-NEXT: } @@ -86,20 +64,12 @@ double f2(double x, double y){ // CHECK: void f2_darg0_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { // CHECK-NEXT: double _d__d_x = 0; // CHECK-NEXT: double _d__d_y = 0; -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; // CHECK-NEXT: clad::ValueAndPushforward _d__t0 = {}; // CHECK-NEXT: double _d__d_ans = 0; // CHECK-NEXT: double _d_ans0 = 0; // CHECK-NEXT: double _d_x0 = 1; // CHECK-NEXT: double _d_y0 = 0; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = y; -// CHECK-NEXT: _t2 = _d_x0; -// CHECK-NEXT: _t3 = _d_y0; -// CHECK-NEXT: clad::ValueAndPushforward _t00 = f_pushforward(_t0, _t1, _t2, _t3); +// CHECK-NEXT: clad::ValueAndPushforward _t00 = f_pushforward(x, y, _d_x0, _d_y0); // CHECK-NEXT: double _d_ans = _t00.pushforward; // CHECK-NEXT: double ans = _t00.value; // CHECK-NEXT: goto _label0; @@ -112,7 +82,7 @@ double f2(double x, double y){ // CHECK-NEXT: double _grad1 = 0.; // CHECK-NEXT: double _grad2 = 0.; // CHECK-NEXT: double _grad3 = 0.; -// CHECK-NEXT: f_pushforward_pullback(_t0, _t1, _t2, _t3, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); +// CHECK-NEXT: f_pushforward_pullback(x, y, _d_x0, _d_y0, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: double _r1 = _grad1; @@ -136,20 +106,12 @@ double f2(double x, double y){ // CHECK: void f2_darg1_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { // CHECK-NEXT: double _d__d_x = 0; // CHECK-NEXT: double _d__d_y = 0; -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; // CHECK-NEXT: clad::ValueAndPushforward _d__t0 = {}; // CHECK-NEXT: double _d__d_ans = 0; // CHECK-NEXT: double _d_ans0 = 0; // CHECK-NEXT: double _d_x0 = 0; // CHECK-NEXT: double _d_y0 = 1; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = y; -// CHECK-NEXT: _t2 = _d_x0; -// CHECK-NEXT: _t3 = _d_y0; -// CHECK-NEXT: clad::ValueAndPushforward _t00 = f_pushforward(_t0, _t1, _t2, _t3); +// CHECK-NEXT: clad::ValueAndPushforward _t00 = f_pushforward(x, y, _d_x0, _d_y0); // CHECK-NEXT: double _d_ans = _t00.pushforward; // CHECK-NEXT: double ans = _t00.value; // CHECK-NEXT: goto _label0; @@ -162,7 +124,7 @@ double f2(double x, double y){ // CHECK-NEXT: double _grad1 = 0.; // CHECK-NEXT: double _grad2 = 0.; // CHECK-NEXT: double _grad3 = 0.; -// CHECK-NEXT: f_pushforward_pullback(_t0, _t1, _t2, _t3, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); +// CHECK-NEXT: f_pushforward_pullback(x, y, _d_x0, _d_y0, _d__t0, &_grad0, &_grad1, &_grad2, &_grad3); // CHECK-NEXT: double _r0 = _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: double _r1 = _grad1; diff --git a/test/Hessian/Pointers.C b/test/Hessian/Pointers.C index 89fd3dcbf..bfc2af21f 100644 --- a/test/Hessian/Pointers.C +++ b/test/Hessian/Pointers.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oPointers.out 2>&1 | FileCheck %s // RUN: ./Pointers.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oPointers.out +// RUN: ./Pointers.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" @@ -17,26 +19,18 @@ double nonMemFn(double i, double j) { // CHECK: void nonMemFn_darg0_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { // CHECK-NEXT: double _d__d_i = 0; // CHECK-NEXT: double _d__d_j = 0; -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; // CHECK-NEXT: double _d_i0 = 1; // CHECK-NEXT: double _d_j0 = 0; -// CHECK-NEXT: _t1 = _d_i0; -// CHECK-NEXT: _t0 = j; -// CHECK-NEXT: _t3 = i; -// CHECK-NEXT: _t2 = _d_j0; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; +// CHECK-NEXT: double _r0 = 1 * j; // CHECK-NEXT: _d__d_i += _r0; -// CHECK-NEXT: double _r1 = _t1 * 1; +// CHECK-NEXT: double _r1 = _d_i0 * 1; // CHECK-NEXT: * _d_j += _r1; -// CHECK-NEXT: double _r2 = 1 * _t2; +// CHECK-NEXT: double _r2 = 1 * _d_j0; // CHECK-NEXT: * _d_i += _r2; -// CHECK-NEXT: double _r3 = _t3 * 1; +// CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: _d__d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -50,26 +44,18 @@ double nonMemFn(double i, double j) { // CHECK: void nonMemFn_darg1_grad(double i, double j, clad::array_ref _d_i, clad::array_ref _d_j) { // CHECK-NEXT: double _d__d_i = 0; // CHECK-NEXT: double _d__d_j = 0; -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; // CHECK-NEXT: double _d_i0 = 0; // CHECK-NEXT: double _d_j0 = 1; -// CHECK-NEXT: _t1 = _d_i0; -// CHECK-NEXT: _t0 = j; -// CHECK-NEXT: _t3 = i; -// CHECK-NEXT: _t2 = _d_j0; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; +// CHECK-NEXT: double _r0 = 1 * j; // CHECK-NEXT: _d__d_i += _r0; -// CHECK-NEXT: double _r1 = _t1 * 1; +// CHECK-NEXT: double _r1 = _d_i0 * 1; // CHECK-NEXT: * _d_j += _r1; -// CHECK-NEXT: double _r2 = 1 * _t2; +// CHECK-NEXT: double _r2 = 1 * _d_j0; // CHECK-NEXT: * _d_i += _r2; -// CHECK-NEXT: double _r3 = _t3 * 1; +// CHECK-NEXT: double _r3 = i * 1; // CHECK-NEXT: _d__d_j += _r3; // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Hessian/TemplateFunctors.C b/test/Hessian/TemplateFunctors.C index e37732ba8..e5c7e5bc6 100644 --- a/test/Hessian/TemplateFunctors.C +++ b/test/Hessian/TemplateFunctors.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oTemplateFunctors.out 2>&1 | FileCheck %s // RUN: ./TemplateFunctors.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oTemplateFunctors.out +// RUN: ./TemplateFunctors.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" diff --git a/test/Hessian/constexprTest.C b/test/Hessian/constexprTest.C index 6f9b01451..9430068da 100644 --- a/test/Hessian/constexprTest.C +++ b/test/Hessian/constexprTest.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -std=c++14 -oconstexprTest.out 2>&1 | FileCheck %s // RUN: ./constexprTest.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -std=c++14 -oconstexprTest.out +// RUN: ./constexprTest.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" diff --git a/test/Hessian/testhessUtility.C b/test/Hessian/testhessUtility.C index 369ae8dc0..f927f7fee 100644 --- a/test/Hessian/testhessUtility.C +++ b/test/Hessian/testhessUtility.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -otesthessUtility.out 2>&1 | FileCheck %s // RUN: ./testhessUtility.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -otesthessUtility.out +// RUN: ./testhessUtility.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" diff --git a/test/Jacobian/FunctionCalls.C b/test/Jacobian/FunctionCalls.C index 4e6a216e5..b0b6b8eca 100644 --- a/test/Jacobian/FunctionCalls.C +++ b/test/Jacobian/FunctionCalls.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oFunctionCalls.out 2>&1 | FileCheck %s // RUN: ./FunctionCalls.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oFunctionCalls.out +// RUN: ./FunctionCalls.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -14,20 +16,12 @@ void fn1(double i, double j, double* output) { } // CHECK: void fn1_jac(double i, double j, double *output, double *jacobianMatrix) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: _t0 = i; -// CHECK-NEXT: _t1 = j; // CHECK-NEXT: output[0] = std::pow(i, j); -// CHECK-NEXT: _t2 = j; -// CHECK-NEXT: _t3 = i; // CHECK-NEXT: output[1] = std::pow(j, i); // CHECK-NEXT: { // CHECK-NEXT: double _jac2 = 0.; // CHECK-NEXT: double _jac3 = 0.; -// CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(_t2, _t3, 1, &_jac2, &_jac3); +// CHECK-NEXT: clad::custom_derivatives::pow_pullback(j, i, 1, &_jac2, &_jac3); // CHECK-NEXT: double _r2 = _jac2; // CHECK-NEXT: jacobianMatrix[3UL] += _r2; // CHECK-NEXT: double _r3 = _jac3; @@ -36,7 +30,7 @@ void fn1(double i, double j, double* output) { // CHECK-NEXT: { // CHECK-NEXT: double _jac0 = 0.; // CHECK-NEXT: double _jac1 = 0.; -// CHECK-NEXT: clad::custom_derivatives{{(::std)?}}::pow_pullback(_t0, _t1, 1, &_jac0, &_jac1); +// CHECK-NEXT: clad::custom_derivatives::pow_pullback(i, j, 1, &_jac0, &_jac1); // CHECK-NEXT: double _r0 = _jac0; // CHECK-NEXT: jacobianMatrix[0UL] += _r0; // CHECK-NEXT: double _r1 = _jac1; diff --git a/test/Jacobian/Functors.C b/test/Jacobian/Functors.C index da7b664c4..d3b0953f8 100644 --- a/test/Jacobian/Functors.C +++ b/test/Jacobian/Functors.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oFunctors.out 2>&1 | FileCheck %s // RUN: ./Functors.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oFunctors.out +// RUN: ./Functors.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" @@ -16,52 +18,28 @@ struct Experiment { } // CHECK: void operator_call_jac(double i, double j, double *output, double *jacobianMatrix) { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: double _t4; - // CHECK-NEXT: double _t5; - // CHECK-NEXT: double _t6; - // CHECK-NEXT: double _t7; - // CHECK-NEXT: double _t8; - // CHECK-NEXT: double _t9; - // CHECK-NEXT: double _t10; - // CHECK-NEXT: double _t11; - // CHECK-NEXT: _t3 = this->x; - // CHECK-NEXT: _t2 = i; - // CHECK-NEXT: _t4 = _t3 * _t2; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t5 = _t4 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: output[0] = this->x * i * i * j; - // CHECK-NEXT: _t9 = this->y; - // CHECK-NEXT: _t8 = i; - // CHECK-NEXT: _t10 = _t9 * _t8; - // CHECK-NEXT: _t7 = j; - // CHECK-NEXT: _t11 = _t10 * _t7; - // CHECK-NEXT: _t6 = j; // CHECK-NEXT: output[1] = this->y * i * j * j; // CHECK-NEXT: { - // CHECK-NEXT: double _r6 = 1 * _t6; - // CHECK-NEXT: double _r7 = _r6 * _t7; - // CHECK-NEXT: double _r8 = _r7 * _t8; - // CHECK-NEXT: double _r9 = _t9 * _r7; + // CHECK-NEXT: double _r6 = 1 * j; + // CHECK-NEXT: double _r7 = _r6 * j; + // CHECK-NEXT: double _r8 = _r7 * i; + // CHECK-NEXT: double _r9 = this->y * _r7; // CHECK-NEXT: jacobianMatrix[2UL] += _r9; - // CHECK-NEXT: double _r10 = _t10 * _r6; + // CHECK-NEXT: double _r10 = this->y * i * _r6; // CHECK-NEXT: jacobianMatrix[3UL] += _r10; - // CHECK-NEXT: double _r11 = _t11 * 1; + // CHECK-NEXT: double _r11 = this->y * i * j * 1; // CHECK-NEXT: jacobianMatrix[3UL] += _r11; // CHECK-NEXT: } // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; - // CHECK-NEXT: double _r2 = _r1 * _t2; - // CHECK-NEXT: double _r3 = _t3 * _r1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; + // CHECK-NEXT: double _r2 = _r1 * i; + // CHECK-NEXT: double _r3 = this->x * _r1; // CHECK-NEXT: jacobianMatrix[0UL] += _r3; - // CHECK-NEXT: double _r4 = _t4 * _r0; + // CHECK-NEXT: double _r4 = this->x * i * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r4; - // CHECK-NEXT: double _r5 = _t5 * 1; + // CHECK-NEXT: double _r5 = this->x * i * i * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r5; // CHECK-NEXT: } // CHECK-NEXT: } @@ -79,52 +57,28 @@ struct ExperimentConst { } // CHECK: void operator_call_jac(double i, double j, double *output, double *jacobianMatrix) const { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: double _t4; - // CHECK-NEXT: double _t5; - // CHECK-NEXT: double _t6; - // CHECK-NEXT: double _t7; - // CHECK-NEXT: double _t8; - // CHECK-NEXT: double _t9; - // CHECK-NEXT: double _t10; - // CHECK-NEXT: double _t11; - // CHECK-NEXT: _t3 = this->x; - // CHECK-NEXT: _t2 = i; - // CHECK-NEXT: _t4 = _t3 * _t2; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t5 = _t4 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: output[0] = this->x * i * i * j; - // CHECK-NEXT: _t9 = this->y; - // CHECK-NEXT: _t8 = i; - // CHECK-NEXT: _t10 = _t9 * _t8; - // CHECK-NEXT: _t7 = j; - // CHECK-NEXT: _t11 = _t10 * _t7; - // CHECK-NEXT: _t6 = j; // CHECK-NEXT: output[1] = this->y * i * j * j; // CHECK-NEXT: { - // CHECK-NEXT: double _r6 = 1 * _t6; - // CHECK-NEXT: double _r7 = _r6 * _t7; - // CHECK-NEXT: double _r8 = _r7 * _t8; - // CHECK-NEXT: double _r9 = _t9 * _r7; + // CHECK-NEXT: double _r6 = 1 * j; + // CHECK-NEXT: double _r7 = _r6 * j; + // CHECK-NEXT: double _r8 = _r7 * i; + // CHECK-NEXT: double _r9 = this->y * _r7; // CHECK-NEXT: jacobianMatrix[2UL] += _r9; - // CHECK-NEXT: double _r10 = _t10 * _r6; + // CHECK-NEXT: double _r10 = this->y * i * _r6; // CHECK-NEXT: jacobianMatrix[3UL] += _r10; - // CHECK-NEXT: double _r11 = _t11 * 1; + // CHECK-NEXT: double _r11 = this->y * i * j * 1; // CHECK-NEXT: jacobianMatrix[3UL] += _r11; // CHECK-NEXT: } // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; - // CHECK-NEXT: double _r2 = _r1 * _t2; - // CHECK-NEXT: double _r3 = _t3 * _r1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; + // CHECK-NEXT: double _r2 = _r1 * i; + // CHECK-NEXT: double _r3 = this->x * _r1; // CHECK-NEXT: jacobianMatrix[0UL] += _r3; - // CHECK-NEXT: double _r4 = _t4 * _r0; + // CHECK-NEXT: double _r4 = this->x * i * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r4; - // CHECK-NEXT: double _r5 = _t5 * 1; + // CHECK-NEXT: double _r5 = this->x * i * i * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r5; // CHECK-NEXT: } // CHECK-NEXT: } @@ -142,52 +96,28 @@ struct ExperimentVolatile { } // CHECK: void operator_call_jac(double i, double j, double *output, double *jacobianMatrix) volatile { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: volatile double _t3; - // CHECK-NEXT: double _t4; - // CHECK-NEXT: double _t5; - // CHECK-NEXT: double _t6; - // CHECK-NEXT: double _t7; - // CHECK-NEXT: double _t8; - // CHECK-NEXT: volatile double _t9; - // CHECK-NEXT: double _t10; - // CHECK-NEXT: double _t11; - // CHECK-NEXT: _t3 = this->x; - // CHECK-NEXT: _t2 = i; - // CHECK-NEXT: _t4 = _t3 * _t2; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t5 = _t4 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: output[0] = this->x * i * i * j; - // CHECK-NEXT: _t9 = this->y; - // CHECK-NEXT: _t8 = i; - // CHECK-NEXT: _t10 = _t9 * _t8; - // CHECK-NEXT: _t7 = j; - // CHECK-NEXT: _t11 = _t10 * _t7; - // CHECK-NEXT: _t6 = j; // CHECK-NEXT: output[1] = this->y * i * j * j; // CHECK-NEXT: { - // CHECK-NEXT: double _r6 = 1 * _t6; - // CHECK-NEXT: double _r7 = _r6 * _t7; - // CHECK-NEXT: double _r8 = _r7 * _t8; - // CHECK-NEXT: double _r9 = _t9 * _r7; + // CHECK-NEXT: double _r6 = 1 * j; + // CHECK-NEXT: double _r7 = _r6 * j; + // CHECK-NEXT: double _r8 = _r7 * i; + // CHECK-NEXT: double _r9 = this->y * _r7; // CHECK-NEXT: jacobianMatrix[2UL] += _r9; - // CHECK-NEXT: double _r10 = _t10 * _r6; + // CHECK-NEXT: double _r10 = this->y * i * _r6; // CHECK-NEXT: jacobianMatrix[3UL] += _r10; - // CHECK-NEXT: double _r11 = _t11 * 1; + // CHECK-NEXT: double _r11 = this->y * i * j * 1; // CHECK-NEXT: jacobianMatrix[3UL] += _r11; // CHECK-NEXT: } // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; - // CHECK-NEXT: double _r2 = _r1 * _t2; - // CHECK-NEXT: double _r3 = _t3 * _r1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; + // CHECK-NEXT: double _r2 = _r1 * i; + // CHECK-NEXT: double _r3 = this->x * _r1; // CHECK-NEXT: jacobianMatrix[0UL] += _r3; - // CHECK-NEXT: double _r4 = _t4 * _r0; + // CHECK-NEXT: double _r4 = this->x * i * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r4; - // CHECK-NEXT: double _r5 = _t5 * 1; + // CHECK-NEXT: double _r5 = this->x * i * i * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r5; // CHECK-NEXT: } // CHECK-NEXT: } @@ -205,52 +135,28 @@ struct ExperimentConstVolatile { } // CHECK: void operator_call_jac(double i, double j, double *output, double *jacobianMatrix) const volatile { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: volatile double _t3; - // CHECK-NEXT: double _t4; - // CHECK-NEXT: double _t5; - // CHECK-NEXT: double _t6; - // CHECK-NEXT: double _t7; - // CHECK-NEXT: double _t8; - // CHECK-NEXT: volatile double _t9; - // CHECK-NEXT: double _t10; - // CHECK-NEXT: double _t11; - // CHECK-NEXT: _t3 = this->x; - // CHECK-NEXT: _t2 = i; - // CHECK-NEXT: _t4 = _t3 * _t2; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t5 = _t4 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: output[0] = this->x * i * i * j; - // CHECK-NEXT: _t9 = this->y; - // CHECK-NEXT: _t8 = i; - // CHECK-NEXT: _t10 = _t9 * _t8; - // CHECK-NEXT: _t7 = j; - // CHECK-NEXT: _t11 = _t10 * _t7; - // CHECK-NEXT: _t6 = j; // CHECK-NEXT: output[1] = this->y * i * j * j; // CHECK-NEXT: { - // CHECK-NEXT: double _r6 = 1 * _t6; - // CHECK-NEXT: double _r7 = _r6 * _t7; - // CHECK-NEXT: double _r8 = _r7 * _t8; - // CHECK-NEXT: double _r9 = _t9 * _r7; + // CHECK-NEXT: double _r6 = 1 * j; + // CHECK-NEXT: double _r7 = _r6 * j; + // CHECK-NEXT: double _r8 = _r7 * i; + // CHECK-NEXT: double _r9 = this->y * _r7; // CHECK-NEXT: jacobianMatrix[2UL] += _r9; - // CHECK-NEXT: double _r10 = _t10 * _r6; + // CHECK-NEXT: double _r10 = this->y * i * _r6; // CHECK-NEXT: jacobianMatrix[3UL] += _r10; - // CHECK-NEXT: double _r11 = _t11 * 1; + // CHECK-NEXT: double _r11 = this->y * i * j * 1; // CHECK-NEXT: jacobianMatrix[3UL] += _r11; // CHECK-NEXT: } // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; - // CHECK-NEXT: double _r2 = _r1 * _t2; - // CHECK-NEXT: double _r3 = _t3 * _r1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; + // CHECK-NEXT: double _r2 = _r1 * i; + // CHECK-NEXT: double _r3 = this->x * _r1; // CHECK-NEXT: jacobianMatrix[0UL] += _r3; - // CHECK-NEXT: double _r4 = _t4 * _r0; + // CHECK-NEXT: double _r4 = this->x * i * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r4; - // CHECK-NEXT: double _r5 = _t5 * 1; + // CHECK-NEXT: double _r5 = this->x * i * i * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r5; // CHECK-NEXT: } // CHECK-NEXT: } @@ -270,52 +176,28 @@ namespace outer { } // CHECK: void operator_call_jac(double i, double j, double *output, double *jacobianMatrix) { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: double _t4; - // CHECK-NEXT: double _t5; - // CHECK-NEXT: double _t6; - // CHECK-NEXT: double _t7; - // CHECK-NEXT: double _t8; - // CHECK-NEXT: double _t9; - // CHECK-NEXT: double _t10; - // CHECK-NEXT: double _t11; - // CHECK-NEXT: _t3 = this->x; - // CHECK-NEXT: _t2 = i; - // CHECK-NEXT: _t4 = _t3 * _t2; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t5 = _t4 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: output[0] = this->x * i * i * j; - // CHECK-NEXT: _t9 = this->y; - // CHECK-NEXT: _t8 = i; - // CHECK-NEXT: _t10 = _t9 * _t8; - // CHECK-NEXT: _t7 = j; - // CHECK-NEXT: _t11 = _t10 * _t7; - // CHECK-NEXT: _t6 = j; // CHECK-NEXT: output[1] = this->y * i * j * j; // CHECK-NEXT: { - // CHECK-NEXT: double _r6 = 1 * _t6; - // CHECK-NEXT: double _r7 = _r6 * _t7; - // CHECK-NEXT: double _r8 = _r7 * _t8; - // CHECK-NEXT: double _r9 = _t9 * _r7; + // CHECK-NEXT: double _r6 = 1 * j; + // CHECK-NEXT: double _r7 = _r6 * j; + // CHECK-NEXT: double _r8 = _r7 * i; + // CHECK-NEXT: double _r9 = this->y * _r7; // CHECK-NEXT: jacobianMatrix[2UL] += _r9; - // CHECK-NEXT: double _r10 = _t10 * _r6; + // CHECK-NEXT: double _r10 = this->y * i * _r6; // CHECK-NEXT: jacobianMatrix[3UL] += _r10; - // CHECK-NEXT: double _r11 = _t11 * 1; + // CHECK-NEXT: double _r11 = this->y * i * j * 1; // CHECK-NEXT: jacobianMatrix[3UL] += _r11; // CHECK-NEXT: } // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; - // CHECK-NEXT: double _r2 = _r1 * _t2; - // CHECK-NEXT: double _r3 = _t3 * _r1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; + // CHECK-NEXT: double _r2 = _r1 * i; + // CHECK-NEXT: double _r3 = this->x * _r1; // CHECK-NEXT: jacobianMatrix[0UL] += _r3; - // CHECK-NEXT: double _r4 = _t4 * _r0; + // CHECK-NEXT: double _r4 = this->x * i * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r4; - // CHECK-NEXT: double _r5 = _t5 * 1; + // CHECK-NEXT: double _r5 = this->x * i * i * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r5; // CHECK-NEXT: } // CHECK-NEXT: } @@ -327,40 +209,24 @@ namespace outer { }; // CHECK: inline void operator_call_jac(double i, double j, double *output, double *jacobianMatrix) const { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: double _t4; - // CHECK-NEXT: double _t5; - // CHECK-NEXT: double _t6; - // CHECK-NEXT: double _t7; - // CHECK-NEXT: _t2 = i; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t3 = _t2 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: output[0] = i * i * j; - // CHECK-NEXT: _t6 = i; - // CHECK-NEXT: _t5 = j; - // CHECK-NEXT: _t7 = _t6 * _t5; - // CHECK-NEXT: _t4 = j; // CHECK-NEXT: output[1] = i * j * j; // CHECK-NEXT: { - // CHECK-NEXT: double _r4 = 1 * _t4; - // CHECK-NEXT: double _r5 = _r4 * _t5; + // CHECK-NEXT: double _r4 = 1 * j; + // CHECK-NEXT: double _r5 = _r4 * j; // CHECK-NEXT: jacobianMatrix[2UL] += _r5; - // CHECK-NEXT: double _r6 = _t6 * _r4; + // CHECK-NEXT: double _r6 = i * _r4; // CHECK-NEXT: jacobianMatrix[3UL] += _r6; - // CHECK-NEXT: double _r7 = _t7 * 1; + // CHECK-NEXT: double _r7 = i * j * 1; // CHECK-NEXT: jacobianMatrix[3UL] += _r7; // CHECK-NEXT: } // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: jacobianMatrix[0UL] += _r1; - // CHECK-NEXT: double _r2 = _t2 * _r0; + // CHECK-NEXT: double _r2 = i * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * i * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -400,40 +266,24 @@ int main() { }; // CHECK: inline void operator_call_jac(double i, double j, double *output, double *jacobianMatrix) const { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: double _t4; - // CHECK-NEXT: double _t5; - // CHECK-NEXT: double _t6; - // CHECK-NEXT: double _t7; - // CHECK-NEXT: _t2 = i; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t3 = _t2 * _t1; - // CHECK-NEXT: _t0 = j; // CHECK-NEXT: output[0] = i * i * j; - // CHECK-NEXT: _t6 = i; - // CHECK-NEXT: _t5 = j; - // CHECK-NEXT: _t7 = _t6 * _t5; - // CHECK-NEXT: _t4 = j; // CHECK-NEXT: output[1] = i * j * j; // CHECK-NEXT: { - // CHECK-NEXT: double _r4 = 1 * _t4; - // CHECK-NEXT: double _r5 = _r4 * _t5; + // CHECK-NEXT: double _r4 = 1 * j; + // CHECK-NEXT: double _r5 = _r4 * j; // CHECK-NEXT: jacobianMatrix[2UL] += _r5; - // CHECK-NEXT: double _r6 = _t6 * _r4; + // CHECK-NEXT: double _r6 = i * _r4; // CHECK-NEXT: jacobianMatrix[3UL] += _r6; - // CHECK-NEXT: double _r7 = _t7 * 1; + // CHECK-NEXT: double _r7 = i * j * 1; // CHECK-NEXT: jacobianMatrix[3UL] += _r7; // CHECK-NEXT: } // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; + // CHECK-NEXT: double _r0 = 1 * j; + // CHECK-NEXT: double _r1 = _r0 * i; // CHECK-NEXT: jacobianMatrix[0UL] += _r1; - // CHECK-NEXT: double _r2 = _t2 * _r0; + // CHECK-NEXT: double _r2 = i * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r2; - // CHECK-NEXT: double _r3 = _t3 * 1; + // CHECK-NEXT: double _r3 = i * i * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r3; // CHECK-NEXT: } // CHECK-NEXT: } @@ -444,52 +294,28 @@ int main() { }; // CHECK: inline void operator_call_jac(double i, double jj, double *output, double *jacobianMatrix) const { - // CHECK-NEXT: double _t0; - // CHECK-NEXT: double _t1; - // CHECK-NEXT: double _t2; - // CHECK-NEXT: double _t3; - // CHECK-NEXT: double _t4; - // CHECK-NEXT: double _t5; - // CHECK-NEXT: double _t6; - // CHECK-NEXT: double _t7; - // CHECK-NEXT: double _t8; - // CHECK-NEXT: double _t9; - // CHECK-NEXT: double _t10; - // CHECK-NEXT: double _t11; - // CHECK-NEXT: _t3 = x; - // CHECK-NEXT: _t2 = i; - // CHECK-NEXT: _t4 = _t3 * _t2; - // CHECK-NEXT: _t1 = i; - // CHECK-NEXT: _t5 = _t4 * _t1; - // CHECK-NEXT: _t0 = jj; // CHECK-NEXT: output[0] = x * i * i * jj; - // CHECK-NEXT: _t9 = y; - // CHECK-NEXT: _t8 = i; - // CHECK-NEXT: _t10 = _t9 * _t8; - // CHECK-NEXT: _t7 = jj; - // CHECK-NEXT: _t11 = _t10 * _t7; - // CHECK-NEXT: _t6 = jj; // CHECK-NEXT: output[1] = y * i * jj * jj; // CHECK-NEXT: { - // CHECK-NEXT: double _r6 = 1 * _t6; - // CHECK-NEXT: double _r7 = _r6 * _t7; - // CHECK-NEXT: double _r8 = _r7 * _t8; - // CHECK-NEXT: double _r9 = _t9 * _r7; + // CHECK-NEXT: double _r6 = 1 * jj; + // CHECK-NEXT: double _r7 = _r6 * jj; + // CHECK-NEXT: double _r8 = _r7 * i; + // CHECK-NEXT: double _r9 = y * _r7; // CHECK-NEXT: jacobianMatrix[2UL] += _r9; - // CHECK-NEXT: double _r10 = _t10 * _r6; + // CHECK-NEXT: double _r10 = y * i * _r6; // CHECK-NEXT: jacobianMatrix[3UL] += _r10; - // CHECK-NEXT: double _r11 = _t11 * 1; + // CHECK-NEXT: double _r11 = y * i * jj * 1; // CHECK-NEXT: jacobianMatrix[3UL] += _r11; // CHECK-NEXT: } // CHECK-NEXT: { - // CHECK-NEXT: double _r0 = 1 * _t0; - // CHECK-NEXT: double _r1 = _r0 * _t1; - // CHECK-NEXT: double _r2 = _r1 * _t2; - // CHECK-NEXT: double _r3 = _t3 * _r1; + // CHECK-NEXT: double _r0 = 1 * jj; + // CHECK-NEXT: double _r1 = _r0 * i; + // CHECK-NEXT: double _r2 = _r1 * i; + // CHECK-NEXT: double _r3 = x * _r1; // CHECK-NEXT: jacobianMatrix[0UL] += _r3; - // CHECK-NEXT: double _r4 = _t4 * _r0; + // CHECK-NEXT: double _r4 = x * i * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r4; - // CHECK-NEXT: double _r5 = _t5 * 1; + // CHECK-NEXT: double _r5 = x * i * i * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r5; // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Jacobian/Jacobian.C b/test/Jacobian/Jacobian.C index 0af0ada5a..53196e949 100644 --- a/test/Jacobian/Jacobian.C +++ b/test/Jacobian/Jacobian.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oJacobian.out 2>&1 | FileCheck %s // RUN: ./Jacobian.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oJacobian.out +// RUN: ./Jacobian.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -13,76 +15,44 @@ void f_1(double a, double b, double c, double output[]) { } void f_1_jac(double a, double b, double c, double output[], double *_result); -//CHECK: f_1_jac(double a, double b, double c, double output[], double *jacobianMatrix) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: double _t9; -//CHECK-NEXT: double _t10; -//CHECK-NEXT: double _t11; -//CHECK-NEXT: double _t12; -//CHECK-NEXT: double _t13; -//CHECK-NEXT: double _t14; -//CHECK-NEXT: double _t15; -//CHECK-NEXT: _t2 = a; -//CHECK-NEXT: _t1 = a; -//CHECK-NEXT: _t3 = _t2 * _t1; -//CHECK-NEXT: _t0 = a; +//CHECK:void f_1_jac(double a, double b, double c, double output[], double *jacobianMatrix) { //CHECK-NEXT: output[0] = a * a * a; -//CHECK-NEXT: _t6 = a; -//CHECK-NEXT: _t5 = a; -//CHECK-NEXT: _t7 = _t6 * _t5; -//CHECK-NEXT: _t4 = a; -//CHECK-NEXT: _t10 = b; -//CHECK-NEXT: _t9 = b; -//CHECK-NEXT: _t11 = _t10 * _t9; -//CHECK-NEXT: _t8 = b; //CHECK-NEXT: output[1] = a * a * a + b * b * b; -//CHECK-NEXT: _t13 = c; -//CHECK-NEXT: _t12 = c; -//CHECK-NEXT: _t15 = a; -//CHECK-NEXT: _t14 = a; //CHECK-NEXT: output[2] = c * c * 10 - a * a; //CHECK-NEXT: { //CHECK-NEXT: double _r12 = 1 * 10; -//CHECK-NEXT: double _r13 = _r12 * _t12; +//CHECK-NEXT: double _r13 = _r12 * c; //CHECK-NEXT: jacobianMatrix[8UL] += _r13; -//CHECK-NEXT: double _r14 = _t13 * _r12; +//CHECK-NEXT: double _r14 = c * _r12; //CHECK-NEXT: jacobianMatrix[8UL] += _r14; -//CHECK-NEXT: double _r15 = -1 * _t14; +//CHECK-NEXT: double _r15 = -1 * a; //CHECK-NEXT: jacobianMatrix[6UL] += _r15; -//CHECK-NEXT: double _r16 = _t15 * -1; +//CHECK-NEXT: double _r16 = a * -1; //CHECK-NEXT: jacobianMatrix[6UL] += _r16; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = 1 * _t4; -//CHECK-NEXT: double _r5 = _r4 * _t5; +//CHECK-NEXT: double _r4 = 1 * a; +//CHECK-NEXT: double _r5 = _r4 * a; //CHECK-NEXT: jacobianMatrix[3UL] += _r5; -//CHECK-NEXT: double _r6 = _t6 * _r4; +//CHECK-NEXT: double _r6 = a * _r4; //CHECK-NEXT: jacobianMatrix[3UL] += _r6; -//CHECK-NEXT: double _r7 = _t7 * 1; +//CHECK-NEXT: double _r7 = a * a * 1; //CHECK-NEXT: jacobianMatrix[3UL] += _r7; -//CHECK-NEXT: double _r8 = 1 * _t8; -//CHECK-NEXT: double _r9 = _r8 * _t9; +//CHECK-NEXT: double _r8 = 1 * b; +//CHECK-NEXT: double _r9 = _r8 * b; //CHECK-NEXT: jacobianMatrix[4UL] += _r9; -//CHECK-NEXT: double _r10 = _t10 * _r8; +//CHECK-NEXT: double _r10 = b * _r8; //CHECK-NEXT: jacobianMatrix[4UL] += _r10; -//CHECK-NEXT: double _r11 = _t11 * 1; +//CHECK-NEXT: double _r11 = b * b * 1; //CHECK-NEXT: jacobianMatrix[4UL] += _r11; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; -//CHECK-NEXT: double _r1 = _r0 * _t1; +//CHECK-NEXT: double _r0 = 1 * a; +//CHECK-NEXT: double _r1 = _r0 * a; //CHECK-NEXT: jacobianMatrix[0UL] += _r1; -//CHECK-NEXT: double _r2 = _t2 * _r0; +//CHECK-NEXT: double _r2 = a * _r0; //CHECK-NEXT: jacobianMatrix[0UL] += _r2; -//CHECK-NEXT: double _r3 = _t3 * 1; +//CHECK-NEXT: double _r3 = a * a * 1; //CHECK-NEXT: jacobianMatrix[0UL] += _r3; //CHECK-NEXT: } //CHECK-NEXT:} @@ -99,60 +69,38 @@ void f_3(double x, double y, double z, double *_result) { void f_3_jac(double x, double y, double z, double *_result, double *jacobianMatrix); //CHECK: void f_3_jac(double x, double y, double z, double *_result, double *jacobianMatrix) { //CHECK-NEXT: double _d_constant = 0; -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: double _t8; //CHECK-NEXT: double constant = 42; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t2 = sin(_t1); -//CHECK-NEXT: _t0 = constant; //CHECK-NEXT: _result[0] = sin(x) * constant; -//CHECK-NEXT: _t4 = y; -//CHECK-NEXT: _t5 = sin(_t4); -//CHECK-NEXT: _t3 = constant; //CHECK-NEXT: _result[1] = sin(y) * constant; -//CHECK-NEXT: _t7 = z; -//CHECK-NEXT: _t8 = sin(_t7); -//CHECK-NEXT: _t6 = constant; //CHECK-NEXT: _result[2] = sin(z) * constant; //CHECK-NEXT: { -//CHECK-NEXT: double _r6 = 1 * _t6; -// CHECK-NEXT: double _r7 = _r6 * clad::custom_derivatives{{(::std)?}}::sin_pushforward(_t7, 1.).pushforward; +//CHECK-NEXT: double _r6 = 1 * constant; +//CHECK-NEXT: double _r7 = _r6 * clad::custom_derivatives::sin_pushforward(z, 1.).pushforward; //CHECK-NEXT: jacobianMatrix[8UL] += _r7; -//CHECK-NEXT: double _r8 = _t8 * 1; +//CHECK-NEXT: double _r8 = sin(z) * 1; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r3 = 1 * _t3; -// CHECK-NEXT: double _r4 = _r3 * clad::custom_derivatives{{(::std)?}}::sin_pushforward(_t4, 1.).pushforward; +//CHECK-NEXT: double _r3 = 1 * constant; +//CHECK-NEXT: double _r4 = _r3 * clad::custom_derivatives::sin_pushforward(y, 1.).pushforward; //CHECK-NEXT: jacobianMatrix[4UL] += _r4; -//CHECK-NEXT: double _r5 = _t5 * 1; +//CHECK-NEXT: double _r5 = sin(y) * 1; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; -// CHECK-NEXT: double _r1 = _r0 * clad::custom_derivatives{{(::std)?}}::sin_pushforward(_t1, 1.).pushforward; +//CHECK-NEXT: double _r0 = 1 * constant; +//CHECK-NEXT: double _r1 = _r0 * clad::custom_derivatives::sin_pushforward(x, 1.).pushforward; //CHECK-NEXT: jacobianMatrix[0UL] += _r1; -//CHECK-NEXT: double _r2 = _t2 * 1; +//CHECK-NEXT: double _r2 = sin(x) * 1; //CHECK-NEXT: } //CHECK-NEXT:} double multiply(double x, double y) { return x * y; } //CHECK: void multiply_pullback(double x, double y, double _d_y0, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = y; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_y0 * _t0; +//CHECK-NEXT: double _r0 = _d_y0 * y; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d_y0; +//CHECK-NEXT: double _r1 = x * _d_y0; //CHECK-NEXT: * _d_y += _r1; //CHECK-NEXT: } //CHECK-NEXT:} @@ -168,66 +116,42 @@ void f_4(double x, double y, double z, double *_result) { void f_4_jac(double x, double y, double z, double *_result, double *jacobianMatrix); //CHECK: void f_4_jac(double x, double y, double z, double *_result, double *jacobianMatrix) { //CHECK-NEXT: double _d_constant = 0; -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: double _t9; -//CHECK-NEXT: double _t10; -//CHECK-NEXT: double _t11; //CHECK-NEXT: double constant = 42; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t2 = y; -//CHECK-NEXT: _t3 = multiply(_t1, _t2); -//CHECK-NEXT: _t0 = constant; //CHECK-NEXT: _result[0] = multiply(x, y) * constant; -//CHECK-NEXT: _t5 = y; -//CHECK-NEXT: _t6 = z; -//CHECK-NEXT: _t7 = multiply(_t5, _t6); -//CHECK-NEXT: _t4 = constant; //CHECK-NEXT: _result[1] = multiply(y, z) * constant; -//CHECK-NEXT: _t9 = z; -//CHECK-NEXT: _t10 = x; -//CHECK-NEXT: _t11 = multiply(_t9, _t10); -//CHECK-NEXT: _t8 = constant; //CHECK-NEXT: _result[2] = multiply(z, x) * constant; //CHECK-NEXT: { -//CHECK-NEXT: double _r8 = 1 * _t8; +//CHECK-NEXT: double _r8 = 1 * constant; //CHECK-NEXT: double _jac4 = 0.; //CHECK-NEXT: double _jac5 = 0.; -//CHECK-NEXT: multiply_pullback(_t9, _t10, _r8, &_jac4, &_jac5); +//CHECK-NEXT: multiply_pullback(z, x, _r8, &_jac4, &_jac5); //CHECK-NEXT: double _r9 = _jac4; //CHECK-NEXT: jacobianMatrix[8UL] += _r9; //CHECK-NEXT: double _r10 = _jac5; //CHECK-NEXT: jacobianMatrix[6UL] += _r10; -//CHECK-NEXT: double _r11 = _t11 * 1; +//CHECK-NEXT: double _r11 = multiply(z, x) * 1; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = 1 * _t4; +//CHECK-NEXT: double _r4 = 1 * constant; //CHECK-NEXT: double _jac2 = 0.; //CHECK-NEXT: double _jac3 = 0.; -//CHECK-NEXT: multiply_pullback(_t5, _t6, _r4, &_jac2, &_jac3); +//CHECK-NEXT: multiply_pullback(y, z, _r4, &_jac2, &_jac3); //CHECK-NEXT: double _r5 = _jac2; //CHECK-NEXT: jacobianMatrix[4UL] += _r5; //CHECK-NEXT: double _r6 = _jac3; //CHECK-NEXT: jacobianMatrix[5UL] += _r6; -//CHECK-NEXT: double _r7 = _t7 * 1; +//CHECK-NEXT: double _r7 = multiply(y, z) * 1; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * constant; //CHECK-NEXT: double _jac0 = 0.; //CHECK-NEXT: double _jac1 = 0.; -//CHECK-NEXT: multiply_pullback(_t1, _t2, _r0, &_jac0, &_jac1); +//CHECK-NEXT: multiply_pullback(x, y, _r0, &_jac0, &_jac1); //CHECK-NEXT: double _r1 = _jac0; //CHECK-NEXT: jacobianMatrix[0UL] += _r1; //CHECK-NEXT: double _r2 = _jac1; //CHECK-NEXT: jacobianMatrix[1UL] += _r2; -//CHECK-NEXT: double _r3 = _t3 * 1; +//CHECK-NEXT: double _r3 = multiply(x, y) * 1; //CHECK-NEXT: } //CHECK-NEXT:} @@ -235,70 +159,38 @@ void f_1_jac_0(double a, double b, double c, double output[], double *jacobianMa // CHECK: void f_1_jac_0(double a, double b, double c, double output[], double *jacobianMatrix) { // CHECK-NEXT: double _d_b = 0; // CHECK-NEXT: double _d_c = 0; -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: double _t5; -// CHECK-NEXT: double _t6; -// CHECK-NEXT: double _t7; -// CHECK-NEXT: double _t8; -// CHECK-NEXT: double _t9; -// CHECK-NEXT: double _t10; -// CHECK-NEXT: double _t11; -// CHECK-NEXT: double _t12; -// CHECK-NEXT: double _t13; -// CHECK-NEXT: double _t14; -// CHECK-NEXT: double _t15; -// CHECK-NEXT: _t2 = a; -// CHECK-NEXT: _t1 = a; -// CHECK-NEXT: _t3 = _t2 * _t1; -// CHECK-NEXT: _t0 = a; // CHECK-NEXT: output[0] = a * a * a; -// CHECK-NEXT: _t6 = a; -// CHECK-NEXT: _t5 = a; -// CHECK-NEXT: _t7 = _t6 * _t5; -// CHECK-NEXT: _t4 = a; -// CHECK-NEXT: _t10 = b; -// CHECK-NEXT: _t9 = b; -// CHECK-NEXT: _t11 = _t10 * _t9; -// CHECK-NEXT: _t8 = b; // CHECK-NEXT: output[1] = a * a * a + b * b * b; -// CHECK-NEXT: _t13 = c; -// CHECK-NEXT: _t12 = c; -// CHECK-NEXT: _t15 = a; -// CHECK-NEXT: _t14 = a; // CHECK-NEXT: output[2] = c * c * 10 - a * a; // CHECK-NEXT: { // CHECK-NEXT: double _r12 = 1 * 10; -// CHECK-NEXT: double _r13 = _r12 * _t12; -// CHECK-NEXT: double _r14 = _t13 * _r12; -// CHECK-NEXT: double _r15 = -1 * _t14; +// CHECK-NEXT: double _r13 = _r12 * c; +// CHECK-NEXT: double _r14 = c * _r12; +// CHECK-NEXT: double _r15 = -1 * a; // CHECK-NEXT: jacobianMatrix[2UL] += _r15; -// CHECK-NEXT: double _r16 = _t15 * -1; +// CHECK-NEXT: double _r16 = a * -1; // CHECK-NEXT: jacobianMatrix[2UL] += _r16; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: double _r4 = 1 * _t4; -// CHECK-NEXT: double _r5 = _r4 * _t5; +// CHECK-NEXT: double _r4 = 1 * a; +// CHECK-NEXT: double _r5 = _r4 * a; // CHECK-NEXT: jacobianMatrix[1UL] += _r5; -// CHECK-NEXT: double _r6 = _t6 * _r4; +// CHECK-NEXT: double _r6 = a * _r4; // CHECK-NEXT: jacobianMatrix[1UL] += _r6; -// CHECK-NEXT: double _r7 = _t7 * 1; +// CHECK-NEXT: double _r7 = a * a * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r7; -// CHECK-NEXT: double _r8 = 1 * _t8; -// CHECK-NEXT: double _r9 = _r8 * _t9; -// CHECK-NEXT: double _r10 = _t10 * _r8; -// CHECK-NEXT: double _r11 = _t11 * 1; +// CHECK-NEXT: double _r8 = 1 * b; +// CHECK-NEXT: double _r9 = _r8 * b; +// CHECK-NEXT: double _r10 = b * _r8; +// CHECK-NEXT: double _r11 = b * b * 1; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; -// CHECK-NEXT: double _r1 = _r0 * _t1; +// CHECK-NEXT: double _r0 = 1 * a; +// CHECK-NEXT: double _r1 = _r0 * a; // CHECK-NEXT: jacobianMatrix[0UL] += _r1; -// CHECK-NEXT: double _r2 = _t2 * _r0; +// CHECK-NEXT: double _r2 = a * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r2; -// CHECK-NEXT: double _r3 = _t3 * 1; +// CHECK-NEXT: double _r3 = a * a * 1; // CHECK-NEXT: jacobianMatrix[0UL] += _r3; // CHECK-NEXT: } // CHECK-NEXT:} diff --git a/test/Jacobian/Pointers.C b/test/Jacobian/Pointers.C index 9629d7975..3245aaed8 100644 --- a/test/Jacobian/Pointers.C +++ b/test/Jacobian/Pointers.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oPointers.out 2>&1 | FileCheck %s // RUN: ./Pointers.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oPointers.out +// RUN: ./Pointers.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" diff --git a/test/Jacobian/TemplateFunctors.C b/test/Jacobian/TemplateFunctors.C index 2c206bc34..ed1e3ce8d 100644 --- a/test/Jacobian/TemplateFunctors.C +++ b/test/Jacobian/TemplateFunctors.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oTemplateFunctors.out 2>&1 | FileCheck %s // RUN: ./TemplateFunctors.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oTemplateFunctors.out +// RUN: ./TemplateFunctors.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" @@ -15,54 +17,28 @@ template struct Experiment { }; // CHECK: void operator_call_jac(double i, double j, double *output, double *jacobianMatrix) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: double _t2; -// CHECK-NEXT: double _t3; -// CHECK-NEXT: double _t4; -// CHECK-NEXT: double _t5; -// CHECK-NEXT: double _t6; -// CHECK-NEXT: double _t7; -// CHECK-NEXT: double _t8; -// CHECK-NEXT: double _t9; -// CHECK-NEXT: double _t10; -// CHECK-NEXT: double _t11; -// CHECK-NEXT: double _t12; -// CHECK-NEXT: _t3 = this->x; -// CHECK-NEXT: _t2 = this->y; -// CHECK-NEXT: _t4 = _t3 * _t2; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t5 = _t4 * _t1; -// CHECK-NEXT: _t0 = j; // CHECK-NEXT: output[0] = this->x * this->y * i * j; -// CHECK-NEXT: _t9 = this->x; -// CHECK-NEXT: _t10 = 2 * _t9; -// CHECK-NEXT: _t8 = this->y; -// CHECK-NEXT: _t11 = _t10 * _t8; -// CHECK-NEXT: _t7 = i; -// CHECK-NEXT: _t12 = _t11 * _t7; -// CHECK-NEXT: _t6 = j; // CHECK-NEXT: output[1] = 2 * this->x * this->y * i * j; // CHECK-NEXT: { -// CHECK-NEXT: double _r6 = 1 * _t6; -// CHECK-NEXT: double _r7 = _r6 * _t7; -// CHECK-NEXT: double _r8 = _r7 * _t8; -// CHECK-NEXT: double _r9 = _r8 * _t9; +// CHECK-NEXT: double _r6 = 1 * j; +// CHECK-NEXT: double _r7 = _r6 * i; +// CHECK-NEXT: double _r8 = _r7 * this->y; +// CHECK-NEXT: double _r9 = _r8 * this->x; // CHECK-NEXT: double _r10 = 2 * _r8; -// CHECK-NEXT: double _r11 = _t10 * _r7; -// CHECK-NEXT: double _r12 = _t11 * _r6; +// CHECK-NEXT: double _r11 = 2 * this->x * _r7; +// CHECK-NEXT: double _r12 = 2 * this->x * this->y * _r6; // CHECK-NEXT: jacobianMatrix[2UL] += _r12; -// CHECK-NEXT: double _r13 = _t12 * 1; +// CHECK-NEXT: double _r13 = 2 * this->x * this->y * i * 1; // CHECK-NEXT: jacobianMatrix[3UL] += _r13; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: double _r0 = 1 * _t0; -// CHECK-NEXT: double _r1 = _r0 * _t1; -// CHECK-NEXT: double _r2 = _r1 * _t2; -// CHECK-NEXT: double _r3 = _t3 * _r1; -// CHECK-NEXT: double _r4 = _t4 * _r0; +// CHECK-NEXT: double _r0 = 1 * j; +// CHECK-NEXT: double _r1 = _r0 * i; +// CHECK-NEXT: double _r2 = _r1 * this->y; +// CHECK-NEXT: double _r3 = this->x * _r1; +// CHECK-NEXT: double _r4 = this->x * this->y * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r4; -// CHECK-NEXT: double _r5 = _t5 * 1; +// CHECK-NEXT: double _r5 = this->x * this->y * i * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r5; // CHECK-NEXT: } // CHECK-NEXT: } @@ -78,68 +54,34 @@ template <> struct Experiment { }; // CHECK: void operator_call_jac(long double i, long double j, long double *output, long double *jacobianMatrix) { -// CHECK-NEXT: long double _t0; -// CHECK-NEXT: long double _t1; -// CHECK-NEXT: long double _t2; -// CHECK-NEXT: long double _t3; -// CHECK-NEXT: long double _t4; -// CHECK-NEXT: long double _t5; -// CHECK-NEXT: long double _t6; -// CHECK-NEXT: long double _t7; -// CHECK-NEXT: long double _t8; -// CHECK-NEXT: long double _t9; -// CHECK-NEXT: long double _t10; -// CHECK-NEXT: long double _t11; -// CHECK-NEXT: long double _t12; -// CHECK-NEXT: long double _t13; -// CHECK-NEXT: long double _t14; -// CHECK-NEXT: long double _t15; -// CHECK-NEXT: long double _t16; -// CHECK-NEXT: _t4 = this->x; -// CHECK-NEXT: _t3 = this->y; -// CHECK-NEXT: _t5 = _t4 * _t3; -// CHECK-NEXT: _t2 = i; -// CHECK-NEXT: _t6 = _t5 * _t2; -// CHECK-NEXT: _t1 = i; -// CHECK-NEXT: _t7 = _t6 * _t1; -// CHECK-NEXT: _t0 = j; // CHECK-NEXT: output[0] = this->x * this->y * i * i * j; -// CHECK-NEXT: _t12 = this->x; -// CHECK-NEXT: _t13 = 2 * _t12; -// CHECK-NEXT: _t11 = this->y; -// CHECK-NEXT: _t14 = _t13 * _t11; -// CHECK-NEXT: _t10 = i; -// CHECK-NEXT: _t15 = _t14 * _t10; -// CHECK-NEXT: _t9 = i; -// CHECK-NEXT: _t16 = _t15 * _t9; -// CHECK-NEXT: _t8 = j; // CHECK-NEXT: output[1] = 2 * this->x * this->y * i * i * j; // CHECK-NEXT: { -// CHECK-NEXT: long double _r8 = 1 * _t8; -// CHECK-NEXT: long double _r9 = _r8 * _t9; -// CHECK-NEXT: long double _r10 = _r9 * _t10; -// CHECK-NEXT: long double _r11 = _r10 * _t11; -// CHECK-NEXT: long double _r12 = _r11 * _t12; +// CHECK-NEXT: long double _r8 = 1 * j; +// CHECK-NEXT: long double _r9 = _r8 * i; +// CHECK-NEXT: long double _r10 = _r9 * i; +// CHECK-NEXT: long double _r11 = _r10 * this->y; +// CHECK-NEXT: long double _r12 = _r11 * this->x; // CHECK-NEXT: long double _r13 = 2 * _r11; -// CHECK-NEXT: long double _r14 = _t13 * _r10; -// CHECK-NEXT: long double _r15 = _t14 * _r9; +// CHECK-NEXT: long double _r14 = 2 * this->x * _r10; +// CHECK-NEXT: long double _r15 = 2 * this->x * this->y * _r9; // CHECK-NEXT: jacobianMatrix[2UL] += _r15; -// CHECK-NEXT: long double _r16 = _t15 * _r8; +// CHECK-NEXT: long double _r16 = 2 * this->x * this->y * i * _r8; // CHECK-NEXT: jacobianMatrix[2UL] += _r16; -// CHECK-NEXT: long double _r17 = _t16 * 1; +// CHECK-NEXT: long double _r17 = 2 * this->x * this->y * i * i * 1; // CHECK-NEXT: jacobianMatrix[3UL] += _r17; // CHECK-NEXT: } // CHECK-NEXT: { -// CHECK-NEXT: long double _r0 = 1 * _t0; -// CHECK-NEXT: long double _r1 = _r0 * _t1; -// CHECK-NEXT: long double _r2 = _r1 * _t2; -// CHECK-NEXT: long double _r3 = _r2 * _t3; -// CHECK-NEXT: long double _r4 = _t4 * _r2; -// CHECK-NEXT: long double _r5 = _t5 * _r1; +// CHECK-NEXT: long double _r0 = 1 * j; +// CHECK-NEXT: long double _r1 = _r0 * i; +// CHECK-NEXT: long double _r2 = _r1 * i; +// CHECK-NEXT: long double _r3 = _r2 * this->y; +// CHECK-NEXT: long double _r4 = this->x * _r2; +// CHECK-NEXT: long double _r5 = this->x * this->y * _r1; // CHECK-NEXT: jacobianMatrix[0UL] += _r5; -// CHECK-NEXT: long double _r6 = _t6 * _r0; +// CHECK-NEXT: long double _r6 = this->x * this->y * i * _r0; // CHECK-NEXT: jacobianMatrix[0UL] += _r6; -// CHECK-NEXT: long double _r7 = _t7 * 1; +// CHECK-NEXT: long double _r7 = this->x * this->y * i * i * 1; // CHECK-NEXT: jacobianMatrix[1UL] += _r7; // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Jacobian/constexprTest.C b/test/Jacobian/constexprTest.C index 8fa166511..65f680ee4 100644 --- a/test/Jacobian/constexprTest.C +++ b/test/Jacobian/constexprTest.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -std=c++14 -oconstexprTest.out 2>&1 | FileCheck %s // RUN: ./constexprTest.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -std=c++14 -oconstexprTest.out +// RUN: ./constexprTest.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" @@ -18,37 +20,25 @@ constexpr void fn_mul(double i, double j, double *res) { } //CHECK: constexpr void fn_mul_jac(double i, double j, double *res, double *jacobianMatrix) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: _t1 = i; -//CHECK-NEXT: _t0 = i; //CHECK-NEXT: res[0] = i * i; -//CHECK-NEXT: _t3 = j; -//CHECK-NEXT: _t2 = j; //CHECK-NEXT: res[1] = j * j; -//CHECK-NEXT: _t5 = i; -//CHECK-NEXT: _t4 = j; //CHECK-NEXT: res[2] = i * j; //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = 1 * _t4; +//CHECK-NEXT: double _r4 = 1 * j; //CHECK-NEXT: jacobianMatrix[4UL] += _r4; -//CHECK-NEXT: double _r5 = _t5 * 1; +//CHECK-NEXT: double _r5 = i * 1; //CHECK-NEXT: jacobianMatrix[5UL] += _r5; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r2 = 1 * _t2; +//CHECK-NEXT: double _r2 = 1 * j; //CHECK-NEXT: jacobianMatrix[3UL] += _r2; -//CHECK-NEXT: double _r3 = _t3 * 1; +//CHECK-NEXT: double _r3 = j * 1; //CHECK-NEXT: jacobianMatrix[3UL] += _r3; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * i; //CHECK-NEXT: jacobianMatrix[0UL] += _r0; -//CHECK-NEXT: double _r1 = _t1 * 1; +//CHECK-NEXT: double _r1 = i * 1; //CHECK-NEXT: jacobianMatrix[0UL] += _r1; //CHECK-NEXT: } //CHECK-NEXT:} @@ -60,75 +50,43 @@ constexpr void f_1(double x, double y, double z, double output[]) { } //CHECK: constexpr void f_1_jac(double x, double y, double z, double output[], double *jacobianMatrix) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: double _t9; -//CHECK-NEXT: double _t10; -//CHECK-NEXT: double _t11; -//CHECK-NEXT: double _t12; -//CHECK-NEXT: double _t13; -//CHECK-NEXT: double _t14; -//CHECK-NEXT: double _t15; -//CHECK-NEXT: _t2 = x; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t3 = _t2 * _t1; -//CHECK-NEXT: _t0 = x; //CHECK-NEXT: output[0] = x * x * x; -//CHECK-NEXT: _t6 = x; -//CHECK-NEXT: _t5 = y; -//CHECK-NEXT: _t7 = _t6 * _t5; -//CHECK-NEXT: _t4 = x; -//CHECK-NEXT: _t10 = y; -//CHECK-NEXT: _t9 = x; -//CHECK-NEXT: _t11 = _t10 * _t9; -//CHECK-NEXT: _t8 = x; //CHECK-NEXT: output[1] = x * y * x + y * x * x; -//CHECK-NEXT: _t13 = z; -//CHECK-NEXT: _t12 = x; -//CHECK-NEXT: _t15 = y; -//CHECK-NEXT: _t14 = z; //CHECK-NEXT: output[2] = z * x * 10 - y * z; //CHECK-NEXT: { //CHECK-NEXT: double _r12 = 1 * 10; -//CHECK-NEXT: double _r13 = _r12 * _t12; +//CHECK-NEXT: double _r13 = _r12 * x; //CHECK-NEXT: jacobianMatrix[8UL] += _r13; -//CHECK-NEXT: double _r14 = _t13 * _r12; +//CHECK-NEXT: double _r14 = z * _r12; //CHECK-NEXT: jacobianMatrix[6UL] += _r14; -//CHECK-NEXT: double _r15 = -1 * _t14; +//CHECK-NEXT: double _r15 = -1 * z; //CHECK-NEXT: jacobianMatrix[7UL] += _r15; -//CHECK-NEXT: double _r16 = _t15 * -1; +//CHECK-NEXT: double _r16 = y * -1; //CHECK-NEXT: jacobianMatrix[8UL] += _r16; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = 1 * _t4; -//CHECK-NEXT: double _r5 = _r4 * _t5; +//CHECK-NEXT: double _r4 = 1 * x; +//CHECK-NEXT: double _r5 = _r4 * y; //CHECK-NEXT: jacobianMatrix[3UL] += _r5; -//CHECK-NEXT: double _r6 = _t6 * _r4; +//CHECK-NEXT: double _r6 = x * _r4; //CHECK-NEXT: jacobianMatrix[4UL] += _r6; -//CHECK-NEXT: double _r7 = _t7 * 1; +//CHECK-NEXT: double _r7 = x * y * 1; //CHECK-NEXT: jacobianMatrix[3UL] += _r7; -//CHECK-NEXT: double _r8 = 1 * _t8; -//CHECK-NEXT: double _r9 = _r8 * _t9; +//CHECK-NEXT: double _r8 = 1 * x; +//CHECK-NEXT: double _r9 = _r8 * x; //CHECK-NEXT: jacobianMatrix[4UL] += _r9; -//CHECK-NEXT: double _r10 = _t10 * _r8; +//CHECK-NEXT: double _r10 = y * _r8; //CHECK-NEXT: jacobianMatrix[3UL] += _r10; -//CHECK-NEXT: double _r11 = _t11 * 1; +//CHECK-NEXT: double _r11 = y * x * 1; //CHECK-NEXT: jacobianMatrix[3UL] += _r11; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; -//CHECK-NEXT: double _r1 = _r0 * _t1; +//CHECK-NEXT: double _r0 = 1 * x; +//CHECK-NEXT: double _r1 = _r0 * x; //CHECK-NEXT: jacobianMatrix[0UL] += _r1; -//CHECK-NEXT: double _r2 = _t2 * _r0; +//CHECK-NEXT: double _r2 = x * _r0; //CHECK-NEXT: jacobianMatrix[0UL] += _r2; -//CHECK-NEXT: double _r3 = _t3 * 1; +//CHECK-NEXT: double _r3 = x * x * 1; //CHECK-NEXT: jacobianMatrix[0UL] += _r3; //CHECK-NEXT: } //CHECK-NEXT:} diff --git a/test/Jacobian/testUtility.C b/test/Jacobian/testUtility.C index 9919e7095..1d43ca589 100644 --- a/test/Jacobian/testUtility.C +++ b/test/Jacobian/testUtility.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -otestUtility.out 2>&1 | FileCheck %s // RUN: ./testUtility.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -otestUtility.out +// RUN: ./testUtility.out | FileCheck -check-prefix=CHECK-EXEC %s // CHECK-NOT: {{.*error|warning|note:.*}} #include "clad/Differentiator/Differentiator.h" @@ -18,37 +20,25 @@ void fn_mul(double i, double j, double *res) { } //CHECK: void fn_mul_jac(double i, double j, double *res, double *jacobianMatrix) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: _t1 = i; -//CHECK-NEXT: _t0 = i; //CHECK-NEXT: res[0] = i * i; -//CHECK-NEXT: _t3 = j; -//CHECK-NEXT: _t2 = j; //CHECK-NEXT: res[1] = j * j; -//CHECK-NEXT: _t5 = i; -//CHECK-NEXT: _t4 = j; //CHECK-NEXT: res[2] = i * j; //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = 1 * _t4; +//CHECK-NEXT: double _r4 = 1 * j; //CHECK-NEXT: jacobianMatrix[4UL] += _r4; -//CHECK-NEXT: double _r5 = _t5 * 1; +//CHECK-NEXT: double _r5 = i * 1; //CHECK-NEXT: jacobianMatrix[5UL] += _r5; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r2 = 1 * _t2; +//CHECK-NEXT: double _r2 = 1 * j; //CHECK-NEXT: jacobianMatrix[3UL] += _r2; -//CHECK-NEXT: double _r3 = _t3 * 1; +//CHECK-NEXT: double _r3 = j * 1; //CHECK-NEXT: jacobianMatrix[3UL] += _r3; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; +//CHECK-NEXT: double _r0 = 1 * i; //CHECK-NEXT: jacobianMatrix[0UL] += _r0; -//CHECK-NEXT: double _r1 = _t1 * 1; +//CHECK-NEXT: double _r1 = i * 1; //CHECK-NEXT: jacobianMatrix[0UL] += _r1; //CHECK-NEXT: } //CHECK-NEXT:} @@ -61,75 +51,43 @@ void f_1(double x, double y, double z, double output[]) { } //CHECK: void f_1_jac(double x, double y, double z, double output[], double *jacobianMatrix) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: double _t4; -//CHECK-NEXT: double _t5; -//CHECK-NEXT: double _t6; -//CHECK-NEXT: double _t7; -//CHECK-NEXT: double _t8; -//CHECK-NEXT: double _t9; -//CHECK-NEXT: double _t10; -//CHECK-NEXT: double _t11; -//CHECK-NEXT: double _t12; -//CHECK-NEXT: double _t13; -//CHECK-NEXT: double _t14; -//CHECK-NEXT: double _t15; -//CHECK-NEXT: _t2 = x; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t3 = _t2 * _t1; -//CHECK-NEXT: _t0 = x; //CHECK-NEXT: output[0] = x * x * x; -//CHECK-NEXT: _t6 = x; -//CHECK-NEXT: _t5 = y; -//CHECK-NEXT: _t7 = _t6 * _t5; -//CHECK-NEXT: _t4 = x; -//CHECK-NEXT: _t10 = y; -//CHECK-NEXT: _t9 = x; -//CHECK-NEXT: _t11 = _t10 * _t9; -//CHECK-NEXT: _t8 = x; //CHECK-NEXT: output[1] = x * y * x + y * x * x; -//CHECK-NEXT: _t13 = z; -//CHECK-NEXT: _t12 = x; -//CHECK-NEXT: _t15 = y; -//CHECK-NEXT: _t14 = z; //CHECK-NEXT: output[2] = z * x * 10 - y * z; //CHECK-NEXT: { //CHECK-NEXT: double _r12 = 1 * 10; -//CHECK-NEXT: double _r13 = _r12 * _t12; +//CHECK-NEXT: double _r13 = _r12 * x; //CHECK-NEXT: jacobianMatrix[8UL] += _r13; -//CHECK-NEXT: double _r14 = _t13 * _r12; +//CHECK-NEXT: double _r14 = z * _r12; //CHECK-NEXT: jacobianMatrix[6UL] += _r14; -//CHECK-NEXT: double _r15 = -1 * _t14; +//CHECK-NEXT: double _r15 = -1 * z; //CHECK-NEXT: jacobianMatrix[7UL] += _r15; -//CHECK-NEXT: double _r16 = _t15 * -1; +//CHECK-NEXT: double _r16 = y * -1; //CHECK-NEXT: jacobianMatrix[8UL] += _r16; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r4 = 1 * _t4; -//CHECK-NEXT: double _r5 = _r4 * _t5; +//CHECK-NEXT: double _r4 = 1 * x; +//CHECK-NEXT: double _r5 = _r4 * y; //CHECK-NEXT: jacobianMatrix[3UL] += _r5; -//CHECK-NEXT: double _r6 = _t6 * _r4; +//CHECK-NEXT: double _r6 = x * _r4; //CHECK-NEXT: jacobianMatrix[4UL] += _r6; -//CHECK-NEXT: double _r7 = _t7 * 1; +//CHECK-NEXT: double _r7 = x * y * 1; //CHECK-NEXT: jacobianMatrix[3UL] += _r7; -//CHECK-NEXT: double _r8 = 1 * _t8; -//CHECK-NEXT: double _r9 = _r8 * _t9; +//CHECK-NEXT: double _r8 = 1 * x; +//CHECK-NEXT: double _r9 = _r8 * x; //CHECK-NEXT: jacobianMatrix[4UL] += _r9; -//CHECK-NEXT: double _r10 = _t10 * _r8; +//CHECK-NEXT: double _r10 = y * _r8; //CHECK-NEXT: jacobianMatrix[3UL] += _r10; -//CHECK-NEXT: double _r11 = _t11 * 1; +//CHECK-NEXT: double _r11 = y * x * 1; //CHECK-NEXT: jacobianMatrix[3UL] += _r11; //CHECK-NEXT: } //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * _t0; -//CHECK-NEXT: double _r1 = _r0 * _t1; +//CHECK-NEXT: double _r0 = 1 * x; +//CHECK-NEXT: double _r1 = _r0 * x; //CHECK-NEXT: jacobianMatrix[0UL] += _r1; -//CHECK-NEXT: double _r2 = _t2 * _r0; +//CHECK-NEXT: double _r2 = x * _r0; //CHECK-NEXT: jacobianMatrix[0UL] += _r2; -//CHECK-NEXT: double _r3 = _t3 * 1; +//CHECK-NEXT: double _r3 = x * x * 1; //CHECK-NEXT: jacobianMatrix[0UL] += _r3; //CHECK-NEXT: } //CHECK-NEXT:} diff --git a/test/Misc/RunDemos.C b/test/Misc/RunDemos.C index 736793560..7950d814a 100644 --- a/test/Misc/RunDemos.C +++ b/test/Misc/RunDemos.C @@ -112,12 +112,14 @@ //CHECK_FLOAT_SUM: float _EERepl_sum0; //CHECK_FLOAT_SUM: unsigned long _t0; //CHECK_FLOAT_SUM: unsigned int _d_i = 0; +//CHECK_FLOAT_SUM: clad::tape _t1 = {}; //CHECK_FLOAT_SUM: clad::tape _EERepl_sum1 = {}; //CHECK_FLOAT_SUM: float sum = 0.; //CHECK_FLOAT_SUM: _EERepl_sum0 = sum; //CHECK_FLOAT_SUM: _t0 = 0; //CHECK_FLOAT_SUM: for (unsigned int i = 0; i < n; i++) { //CHECK_FLOAT_SUM: _t0++; +//CHECK_FLOAT_SUM: clad::push(_t1, sum); //CHECK_FLOAT_SUM: sum = sum + x; //CHECK_FLOAT_SUM: clad::push(_EERepl_sum1, sum); //CHECK_FLOAT_SUM: } @@ -125,19 +127,21 @@ //CHECK_FLOAT_SUM: _label0: //CHECK_FLOAT_SUM: _d_sum += 1; //CHECK_FLOAT_SUM: for (; _t0; _t0--) { +//CHECK_FLOAT_SUM: i--; //CHECK_FLOAT_SUM: { +//CHECK_FLOAT_SUM: sum = clad::pop(_t1); //CHECK_FLOAT_SUM: float _r_d0 = _d_sum; //CHECK_FLOAT_SUM: _d_sum += _r_d0; //CHECK_FLOAT_SUM: * _d_x += _r_d0; //CHECK_FLOAT_SUM: float _r0 = clad::pop(_EERepl_sum1); -//CHECK_FLOAT_SUM: _delta_sum += std::abs(_r_d0 * _r0 * {{.+}}); +//CHECK_FLOAT_SUM: _delta_sum += std::abs(_r_d0 * _r0 * 1.1920928955078125E-7); //CHECK_FLOAT_SUM: _d_sum -= _r_d0; //CHECK_FLOAT_SUM: } //CHECK_FLOAT_SUM: } -//CHECK_FLOAT_SUM: _delta_sum += std::abs(_d_sum * _EERepl_sum0 * {{.+}}); +//CHECK_FLOAT_SUM: _delta_sum += std::abs(_d_sum * _EERepl_sum0 * 1.1920928955078125E-7); //CHECK_FLOAT_SUM: double _delta_x = 0; -//CHECK_FLOAT_SUM: _delta_x += std::abs(* _d_x * x * {{.+}}); -//CHECK_FLOAT_SUM: _final_error += _delta_{{x|sum}} + _delta_{{x|sum}}; +//CHECK_FLOAT_SUM: _delta_x += std::abs(* _d_x * x * 1.1920928955078125E-7); +//CHECK_FLOAT_SUM: _final_error += _delta_x + _delta_sum; //CHECK_FLOAT_SUM: } //-----------------------------------------------------------------------------/ @@ -157,15 +161,18 @@ // CHECK_CUSTOM_MODEL_EXEC-NEXT: float _d_z = 0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: double _delta_z = 0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: float _EERepl_z0; +// CHECK_CUSTOM_MODEL_EXEC-NEXT: float _t0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: float _EERepl_z1; // CHECK_CUSTOM_MODEL_EXEC-NEXT: float z; // CHECK_CUSTOM_MODEL_EXEC-NEXT: _EERepl_z0 = z; +// CHECK_CUSTOM_MODEL_EXEC-NEXT: _t0 = z; // CHECK_CUSTOM_MODEL_EXEC-NEXT: z = x + y; // CHECK_CUSTOM_MODEL_EXEC-NEXT: _EERepl_z1 = z; // CHECK_CUSTOM_MODEL_EXEC-NEXT: goto _label0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: _label0: // CHECK_CUSTOM_MODEL_EXEC-NEXT: _d_z += 1; // CHECK_CUSTOM_MODEL_EXEC-NEXT: { +// CHECK_CUSTOM_MODEL_EXEC-NEXT: z = _t0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: float _r_d0 = _d_z; // CHECK_CUSTOM_MODEL_EXEC-NEXT: * _d_x += _r_d0; // CHECK_CUSTOM_MODEL_EXEC-NEXT: * _d_y += _r_d0; @@ -196,15 +203,18 @@ // CHECK_PRINT_MODEL_EXEC-NEXT: float _d_z = 0; // CHECK_PRINT_MODEL_EXEC-NEXT: double _delta_z = 0; // CHECK_PRINT_MODEL_EXEC-NEXT: float _EERepl_z0; +// CHECK_PRINT_MODEL_EXEC-NEXT: float _t0; // CHECK_PRINT_MODEL_EXEC-NEXT: float _EERepl_z1; // CHECK_PRINT_MODEL_EXEC-NEXT: float z; // CHECK_PRINT_MODEL_EXEC-NEXT: _EERepl_z0 = z; +// CHECK_PRINT_MODEL_EXEC-NEXT: _t0 = z; // CHECK_PRINT_MODEL_EXEC-NEXT: z = x + y; // CHECK_PRINT_MODEL_EXEC-NEXT: _EERepl_z1 = z; // CHECK_PRINT_MODEL_EXEC-NEXT: goto _label0; // CHECK_PRINT_MODEL_EXEC-NEXT: _label0: // CHECK_PRINT_MODEL_EXEC-NEXT: _d_z += 1; // CHECK_PRINT_MODEL_EXEC-NEXT: { +// CHECK_PRINT_MODEL_EXEC-NEXT: z = _t0; // CHECK_PRINT_MODEL_EXEC-NEXT: float _r_d0 = _d_z; // CHECK_PRINT_MODEL_EXEC-NEXT: * _d_x += _r_d0; // CHECK_PRINT_MODEL_EXEC-NEXT: * _d_y += _r_d0; @@ -227,41 +237,27 @@ // RUN: %cladclang %S/../../demos/GradientDescent.cpp -I%S/../../include -oGradientDescent.out | FileCheck -check-prefix CHECK_GRADIENT_DESCENT %s //CHECK_GRADIENT_DESCENT: void f_pullback(double theta_0, double theta_1, double x, double _d_y, clad::array_ref _d_theta_0, clad::array_ref _d_theta_1, clad::array_ref _d_x) { -//CHECK_GRADIENT_DESCENT-NEXT: double _t0; -//CHECK_GRADIENT_DESCENT-NEXT: double _t1; -//CHECK_GRADIENT_DESCENT-NEXT: _t1 = theta_1; -//CHECK_GRADIENT_DESCENT-NEXT: _t0 = x; //CHECK_GRADIENT_DESCENT-NEXT: goto _label0; //CHECK_GRADIENT_DESCENT-NEXT: _label0: //CHECK_GRADIENT_DESCENT-NEXT: { //CHECK_GRADIENT_DESCENT-NEXT: * _d_theta_0 += _d_y; -//CHECK_GRADIENT_DESCENT-NEXT: double _r0 = _d_y * _t0; +//CHECK_GRADIENT_DESCENT-NEXT: double _r0 = _d_y * x; //CHECK_GRADIENT_DESCENT-NEXT: * _d_theta_1 += _r0; -//CHECK_GRADIENT_DESCENT-NEXT: double _r1 = _t1 * _d_y; +//CHECK_GRADIENT_DESCENT-NEXT: double _r1 = theta_1 * _d_y; //CHECK_GRADIENT_DESCENT-NEXT: * _d_x += _r1; //CHECK_GRADIENT_DESCENT-NEXT: } //CHECK_GRADIENT_DESCENT-NEXT: } //CHECK_GRADIENT_DESCENT-NEXT: void cost_grad(double theta_0, double theta_1, double x, double y, clad::array_ref _d_theta_0, clad::array_ref _d_theta_1, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK_GRADIENT_DESCENT-NEXT: double _t0; -//CHECK_GRADIENT_DESCENT-NEXT: double _t1; -//CHECK_GRADIENT_DESCENT-NEXT: double _t2; //CHECK_GRADIENT_DESCENT-NEXT: double _d_f_x = 0; -//CHECK_GRADIENT_DESCENT-NEXT: double _t3; -//CHECK_GRADIENT_DESCENT-NEXT: double _t4; -//CHECK_GRADIENT_DESCENT-NEXT: _t0 = theta_0; -//CHECK_GRADIENT_DESCENT-NEXT: _t1 = theta_1; -//CHECK_GRADIENT_DESCENT-NEXT: _t2 = x; -//CHECK_GRADIENT_DESCENT-NEXT: double f_x = f(_t0, _t1, _t2); -//CHECK_GRADIENT_DESCENT-NEXT: _t4 = (f_x - y); -//CHECK_GRADIENT_DESCENT-NEXT: _t3 = (f_x - y); +//CHECK_GRADIENT_DESCENT-NEXT: double f_x = f(theta_0, theta_1, x); //CHECK_GRADIENT_DESCENT-NEXT: goto _label0; //CHECK_GRADIENT_DESCENT-NEXT: _label0: //CHECK_GRADIENT_DESCENT-NEXT: { -//CHECK_GRADIENT_DESCENT-NEXT: double _r3 = 1 * _t3; +//CHECK_GRADIENT_DESCENT-NEXT: double _r3 = 1 * (f_x - y); //CHECK_GRADIENT_DESCENT-NEXT: _d_f_x += _r3; //CHECK_GRADIENT_DESCENT-NEXT: * _d_y += -_r3; -//CHECK_GRADIENT_DESCENT-NEXT: double _r4 = _t4 * 1; +//CHECK_GRADIENT_DESCENT-NEXT: double _r4 = (f_x - y) * 1; //CHECK_GRADIENT_DESCENT-NEXT: _d_f_x += _r4; //CHECK_GRADIENT_DESCENT-NEXT: * _d_y += -_r4; //CHECK_GRADIENT_DESCENT-NEXT: } @@ -269,7 +265,7 @@ //CHECK_GRADIENT_DESCENT-NEXT: double _grad0 = 0.; //CHECK_GRADIENT_DESCENT-NEXT: double _grad1 = 0.; //CHECK_GRADIENT_DESCENT-NEXT: double _grad2 = 0.; -//CHECK_GRADIENT_DESCENT-NEXT: f_pullback(_t0, _t1, _t2, _d_f_x, &_grad0, &_grad1, &_grad2); +//CHECK_GRADIENT_DESCENT-NEXT: f_pullback(theta_0, theta_1, x, _d_f_x, &_grad0, &_grad1, &_grad2); //CHECK_GRADIENT_DESCENT-NEXT: double _r0 = _grad0; //CHECK_GRADIENT_DESCENT-NEXT: * _d_theta_0 += _r0; //CHECK_GRADIENT_DESCENT-NEXT: double _r1 = _grad1; @@ -341,4 +337,4 @@ // RUN: ./VectorForwardMode.out | FileCheck -check-prefix CHECK_VECTOR_FORWARD_MODE_EXEC %s // CHECK_VECTOR_FORWARD_MODE_EXEC: Vector forward mode w.r.t. all: // CHECK_VECTOR_FORWARD_MODE_EXEC: darr = {0.5, 0.7, 0.9} -// CHECK_VECTOR_FORWARD_MODE_EXEC: dweights = {3, 4, 5} \ No newline at end of file +// CHECK_VECTOR_FORWARD_MODE_EXEC: dweights = {3, 4, 5} diff --git a/test/NestedCalls/NestedCalls.C b/test/NestedCalls/NestedCalls.C index bf2725a2d..42c9e856a 100644 --- a/test/NestedCalls/NestedCalls.C +++ b/test/NestedCalls/NestedCalls.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oNestedCalls.out 2>&1 | FileCheck %s // RUN: ./NestedCalls.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oNestedCalls.out +// RUN: ./NestedCalls.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -38,65 +40,47 @@ double f(double x, double y) { // CHECK-NEXT: } //CHECK: void sq_pullback(double x, double _d_y, clad::array_ref _d_x) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: _t1 = x; -//CHECK-NEXT: _t0 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = _d_y * _t0; +//CHECK-NEXT: double _r0 = _d_y * x; //CHECK-NEXT: * _d_x += _r0; -//CHECK-NEXT: double _r1 = _t1 * _d_y; +//CHECK-NEXT: double _r1 = x * _d_y; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK: void one_pullback(double x, double _d_y, clad::array_ref _d_x) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: double _t3; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: _t1 = std::sin(_t0); -//CHECK-NEXT: _t2 = x; -//CHECK-NEXT: _t3 = std::cos(_t2); //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { //CHECK-NEXT: double _grad0 = 0.; -//CHECK-NEXT: sq_pullback(_t1, _d_y, &_grad0); +//CHECK-NEXT: sq_pullback(std::sin(x), _d_y, &_grad0); //CHECK-NEXT: double _r0 = _grad0; -//CHECK-NEXT: double _r1 = _r0 * clad::custom_derivatives::sin_pushforward(_t0, 1.).pushforward; +//CHECK-NEXT: double _r1 = _r0 * clad::custom_derivatives::sin_pushforward(x, 1.).pushforward; //CHECK-NEXT: * _d_x += _r1; //CHECK-NEXT: double _grad1 = 0.; -//CHECK-NEXT: sq_pullback(_t3, _d_y, &_grad1); +//CHECK-NEXT: sq_pullback(std::cos(x), _d_y, &_grad1); //CHECK-NEXT: double _r2 = _grad1; -//CHECK-NEXT: double _r3 = _r2 * clad::custom_derivatives::cos_pushforward(_t2, 1.).pushforward; +//CHECK-NEXT: double _r3 = _r2 * clad::custom_derivatives::cos_pushforward(x, 1.).pushforward; //CHECK-NEXT: * _d_x += _r3; //CHECK-NEXT: } //CHECK-NEXT: } //CHECK: void f_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -//CHECK-NEXT: double _t0; //CHECK-NEXT: double _d_t = 0; -//CHECK-NEXT: double _t1; -//CHECK-NEXT: double _t2; -//CHECK-NEXT: _t0 = x; -//CHECK-NEXT: double t = one(_t0); -//CHECK-NEXT: _t2 = t; -//CHECK-NEXT: _t1 = y; +//CHECK-NEXT: double t = one(x); //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r1 = 1 * _t1; +//CHECK-NEXT: double _r1 = 1 * y; //CHECK-NEXT: _d_t += _r1; -//CHECK-NEXT: double _r2 = _t2 * 1; +//CHECK-NEXT: double _r2 = t * 1; //CHECK-NEXT: * _d_y += _r2; //CHECK-NEXT: } //CHECK-NEXT: { //CHECK-NEXT: double _grad0 = 0.; -//CHECK-NEXT: one_pullback(_t0, _d_t, &_grad0); +//CHECK-NEXT: one_pullback(x, _d_t, &_grad0); //CHECK-NEXT: double _r0 = _grad0; //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: } diff --git a/test/NumericalDiff/GradientMultiArg.C b/test/NumericalDiff/GradientMultiArg.C index 3a3b19c78..5270965d0 100644 --- a/test/NumericalDiff/GradientMultiArg.C +++ b/test/NumericalDiff/GradientMultiArg.C @@ -1,5 +1,7 @@ // RUN: %cladnumdiffclang %s -I%S/../../include -oGradientMultiArg.out 2>&1 | FileCheck -check-prefix=CHECK %s // RUN: ./GradientMultiArg.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladnumdiffclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oGradientMultiArg.out +// RUN: ./GradientMultiArg.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -13,19 +15,15 @@ double test_1(double x, double y){ } // CHECK: warning: Falling back to numerical differentiation for 'hypot' since no suitable overload was found and clad could not derive it. To disable this feature, compile your programs with -DCLAD_NO_NUM_DIFF. // CHECK: void test_1_grad(double x, double y, clad::array_ref _d_x, clad::array_ref _d_y) { -// CHECK-NEXT: double _t0; -// CHECK-NEXT: double _t1; -// CHECK-NEXT: _t0 = x; -// CHECK-NEXT: _t1 = y; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: double _grad0 = 0.; // CHECK-NEXT: double _grad1 = 0.; -// CHECK-NEXT: clad::tape > _t2 = {}; -// CHECK-NEXT: clad::push(_t2, &_grad0); -// CHECK-NEXT: clad::push(_t2, &_grad1); -// CHECK-NEXT: numerical_diff::central_difference(std::hypot, _t2, 0, _t0, _t1); +// CHECK-NEXT: clad::tape > _t0 = {}; +// CHECK-NEXT: clad::push(_t0, &_grad0); +// CHECK-NEXT: clad::push(_t0, &_grad1); +// CHECK-NEXT: numerical_diff::central_difference(std::hypot, _t0, 0, x, y); // CHECK-NEXT: double _r0 = 1 * _grad0; // CHECK-NEXT: * _d_x += _r0; // CHECK-NEXT: double _r1 = 1 * _grad1; diff --git a/test/NumericalDiff/NoNumDiff.C b/test/NumericalDiff/NoNumDiff.C index b7a8dc091..76749de86 100644 --- a/test/NumericalDiff/NoNumDiff.C +++ b/test/NumericalDiff/NoNumDiff.C @@ -16,8 +16,6 @@ double func(double x) { return std::tanh(x); } //CHECK-NEXT: } //CHECK: void func_grad(double x, clad::array_ref _d_x) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: _t0 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { diff --git a/test/NumericalDiff/NumDiff.C b/test/NumericalDiff/NumDiff.C index d05a05080..e4d46f263 100644 --- a/test/NumericalDiff/NumDiff.C +++ b/test/NumericalDiff/NumDiff.C @@ -11,12 +11,10 @@ double test_1(double x){ //CHECK: warning: Falling back to numerical differentiation for 'log10' since no suitable overload was found and clad could not derive it. To disable this feature, compile your programs with -DCLAD_NO_NUM_DIFF. //CHECK: void test_1_grad(double x, clad::array_ref _d_x) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: _t0 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * numerical_diff::forward_central_difference(tanh, _t0, 0, 0, _t0); +//CHECK-NEXT: double _r0 = 1 * numerical_diff::forward_central_difference(tanh, x, 0, 0, x); //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: } //CHECK-NEXT: } diff --git a/test/NumericalDiff/PrintErrorNumDiff.C b/test/NumericalDiff/PrintErrorNumDiff.C index a1f93531f..4d1cf069e 100644 --- a/test/NumericalDiff/PrintErrorNumDiff.C +++ b/test/NumericalDiff/PrintErrorNumDiff.C @@ -1,5 +1,7 @@ // RUN: %cladnumdiffclang -Xclang -plugin-arg-clad -Xclang -fprint-num-diff-errors %s -I%S/../../include -oPrintErrorNumDiff.out 2>&1 | FileCheck -check-prefix=CHECK %s -// -Xclang -verify 2>&1 RUN: ./PrintErrorNumDiff.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: ./PrintErrorNumDiff.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladnumdiffclang -Xclang -plugin-arg-clad -Xclang -fprint-num-diff-errors -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oPrintErrorNumDiff.out +// RUN: ./PrintErrorNumDiff.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -15,12 +17,10 @@ double test_1(double x){ //CHECK: warning: Falling back to numerical differentiation for 'tanh' since no suitable overload was found and clad could not derive it. To disable this feature, compile your programs with -DCLAD_NO_NUM_DIFF. //CHECK: void test_1_grad(double x, clad::array_ref _d_x) { -//CHECK-NEXT: double _t0; -//CHECK-NEXT: _t0 = x; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: double _r0 = 1 * numerical_diff::forward_central_difference(tanh, _t0, 0, 1, _t0); +//CHECK-NEXT: double _r0 = 1 * numerical_diff::forward_central_difference(tanh, x, 0, 1, x); //CHECK-NEXT: * _d_x += _r0; //CHECK-NEXT: } //CHECK-NEXT: } diff --git a/test/ROOT/Hessian.C b/test/ROOT/Hessian.C index c7ca79325..9fc21d0a0 100644 --- a/test/ROOT/Hessian.C +++ b/test/ROOT/Hessian.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oHessian.out 2>&1 | FileCheck %s // RUN: ./Hessian.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oHessian.out +// RUN: ./Hessian.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} diff --git a/test/ROOT/Interface.C b/test/ROOT/Interface.C index 31261c07c..863566adc 100644 --- a/test/ROOT/Interface.C +++ b/test/ROOT/Interface.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oInterface.out 2>&1 | FileCheck %s // RUN: ./Interface.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oInterface.out +// RUN: ./Interface.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -21,16 +23,12 @@ Double_t f(Double_t* x, Double_t* p) { void f_grad_1(Double_t* x, Double_t* p, clad::array_ref _d_p); // CHECK: void f_grad_1(Double_t *x, Double_t *p, clad::array_ref _d_p) { -// CHECK-NEXT: Double_t _t0; -// CHECK-NEXT: Double_t _t1; -// CHECK-NEXT: _t1 = x[0]; -// CHECK-NEXT: _t0 = p[1]; // CHECK-NEXT: goto _label0; // CHECK-NEXT: _label0: // CHECK-NEXT: { // CHECK-NEXT: _d_p[0] += 1; -// CHECK-NEXT: {{double|Double_t}} _r0 = 1 * _t0; -// CHECK-NEXT: {{double|Double_t}} _r1 = _t1 * 1; +// CHECK-NEXT: {{double|Double_t}} _r0 = 1 * p[1]; +// CHECK-NEXT: {{double|Double_t}} _r1 = x[0] * 1; // CHECK-NEXT: _d_p[1] += _r1; // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/ROOT/TFormula.C b/test/ROOT/TFormula.C index ba53c4d3d..4c052c907 100644 --- a/test/ROOT/TFormula.C +++ b/test/ROOT/TFormula.C @@ -1,5 +1,7 @@ // RUN: %cladclang %s -I%S/../../include -oTFormula.out 2>&1 | FileCheck %s // RUN: ./TFormula.out | FileCheck -check-prefix=CHECK-EXEC %s +// RUN: %cladclang -Xclang -plugin-arg-clad -Xclang -enable-tbr %s -I%S/../../include -oTFormula.out +// RUN: ./TFormula.out | FileCheck -check-prefix=CHECK-EXEC %s //CHECK-NOT: {{.*error|warning|note:.*}} @@ -39,25 +41,17 @@ Double_t TFormula_example(Double_t* x, Double_t* p) { void TFormula_example_grad_1(Double_t* x, Double_t* p, Double_t* _d_p); //CHECK: void TFormula_example_grad_1(Double_t *x, Double_t *p, clad::array_ref _d_p) { -//CHECK-NEXT: {{double|Double_t}} _t0; -//CHECK-NEXT: Double_t _t1; -//CHECK-NEXT: Double_t _t2; -//CHECK-NEXT: Double_t _t3; -//CHECK-NEXT: _t1 = x[0]; -//CHECK-NEXT: _t0 = (p[0] + p[1] + p[2]); -//CHECK-NEXT: _t2 = -p[0]; -//CHECK-NEXT: _t3 = p[1]; //CHECK-NEXT: goto _label0; //CHECK-NEXT: _label0: //CHECK-NEXT: { -//CHECK-NEXT: {{double|Double_t}} _r0 = 1 * _t0; -//CHECK-NEXT: {{double|Double_t}} _r1 = _t1 * 1; +//CHECK-NEXT: {{double|Double_t}} _r0 = 1 * (p[0] + p[1] + p[2]); +//CHECK-NEXT: {{double|Double_t}} _r1 = x[0] * 1; //CHECK-NEXT: _d_p[0] += _r1; //CHECK-NEXT: _d_p[1] += _r1; //CHECK-NEXT: _d_p[2] += _r1; -//CHECK-NEXT: Double_t _r2 = 1 * clad::custom_derivatives{{(::std)?}}::TMath::Exp_pushforward(_t2, 1.).pushforward; +//CHECK-NEXT: Double_t _r2 = 1 * clad::custom_derivatives{{(::std)?}}::TMath::Exp_pushforward(-p[0], 1.).pushforward; //CHECK-NEXT: _d_p[0] += -_r2; -//CHECK-NEXT: Double_t _r3 = 1 * clad::custom_derivatives{{(::std)?}}::TMath::Abs_pushforward(_t3, 1.).pushforward; +//CHECK-NEXT: Double_t _r3 = 1 * clad::custom_derivatives{{(::std)?}}::TMath::Abs_pushforward(p[1], 1.).pushforward; //CHECK-NEXT: _d_p[1] += _r3; //CHECK-NEXT: } //CHECK-NEXT: } diff --git a/test/lit.cfg b/test/lit.cfg index 1797ec687..014f22024 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -40,7 +40,7 @@ config.test_format = lit.formats.ShTest(execute_external) # suffixes: A list of file extensions to treat as test files, this is actually # set by on_clone(). -config.suffixes = ['.C', '.cu'] +config.suffixes = ['.C', '.cpp', '.cu'] # test_source_root: The root path where tests are located. config.test_source_root = os.path.dirname(__file__) diff --git a/tools/ClangPlugin.cpp b/tools/ClangPlugin.cpp index b3c374218..70e39aa1b 100644 --- a/tools/ClangPlugin.cpp +++ b/tools/ClangPlugin.cpp @@ -143,6 +143,12 @@ namespace clad { if (requests.empty()) return true; + // FIXME: flags have to be set manually since DiffCollector's constructor + // does not have access to m_DO. + if (m_DO.EnableTBRAnalysis) + for (DiffRequest& request : requests) + request.EnableTBRAnalysis = true; + // FIXME: Remove the PerformPendingInstantiations altogether. We should // somehow make the relevant functions referenced. // Instantiate all pending for instantiations templates, because we will diff --git a/tools/ClangPlugin.h b/tools/ClangPlugin.h index 4d570019e..3394a0d38 100644 --- a/tools/ClangPlugin.h +++ b/tools/ClangPlugin.h @@ -67,8 +67,8 @@ namespace clad { DifferentiationOptions() : DumpSourceFn(false), DumpSourceFnAST(false), DumpDerivedFn(false), DumpDerivedAST(false), GenerateSourceFile(false), - ValidateClangVersion(true), CustomEstimationModel(false), - PrintNumDiffErrorInfo(false), CustomModelName("") {} + ValidateClangVersion(true), EnableTBRAnalysis(false), + CustomEstimationModel(false), PrintNumDiffErrorInfo(false) {} bool DumpSourceFn : 1; bool DumpSourceFnAST : 1; @@ -76,6 +76,7 @@ namespace clad { bool DumpDerivedAST : 1; bool GenerateSourceFile : 1; bool ValidateClangVersion : 1; + bool EnableTBRAnalysis : 1; bool CustomEstimationModel : 1; bool PrintNumDiffErrorInfo : 1; std::string CustomModelName; @@ -132,6 +133,8 @@ namespace clad { m_DO.GenerateSourceFile = true; } else if (args[i] == "-fno-validate-clang-version") { m_DO.ValidateClangVersion = false; + } else if (args[i] == "-enable-tbr") { + m_DO.EnableTBRAnalysis = true; } else if (args[i] == "-fcustom-estimation-model") { m_DO.CustomEstimationModel = true; if (++i == e) {