diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Reassociate.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/Reassociate.cpp | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index da1737979305..75f0896d4845 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -29,6 +29,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/BasicAliasAnalysis.h" +#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Argument.h" @@ -1929,11 +1930,23 @@ Value *ReassociatePass::OptimizeExpression(BinaryOperator *I, SmallVectorImpl<ValueEntry> &Ops) { // Now that we have the linearized expression tree, try to optimize it. // Start by folding any constants that we found. + const DataLayout &DL = I->getModule()->getDataLayout(); Constant *Cst = nullptr; unsigned Opcode = I->getOpcode(); - while (!Ops.empty() && isa<Constant>(Ops.back().Op)) { - Constant *C = cast<Constant>(Ops.pop_back_val().Op); - Cst = Cst ? ConstantExpr::get(Opcode, C, Cst) : C; + while (!Ops.empty()) { + if (auto *C = dyn_cast<Constant>(Ops.back().Op)) { + if (!Cst) { + Ops.pop_back(); + Cst = C; + continue; + } + if (Constant *Res = ConstantFoldBinaryOpOperands(Opcode, C, Cst, DL)) { + Ops.pop_back(); + Cst = Res; + continue; + } + } + break; } // If there was nothing but constants then we are done. if (Ops.empty()) |