aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/Reassociate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Reassociate.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/Reassociate.cpp19
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())