aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorPete Cooper <peter_cooper@apple.com>2011-12-17 06:32:38 +0000
committerPete Cooper <peter_cooper@apple.com>2011-12-17 06:32:38 +0000
commit93ca12299f3210e300c9ac4f0fd8d6ce5b7d7d60 (patch)
tree541df002e9efbaeed432f3dd090097f62870d8b7 /lib/Transforms
parent5bb210e134c8bc66f77a78bb3aedc118d949698c (diff)
downloadexternal_llvm-93ca12299f3210e300c9ac4f0fd8d6ce5b7d7d60.zip
external_llvm-93ca12299f3210e300c9ac4f0fd8d6ce5b7d7d60.tar.gz
external_llvm-93ca12299f3210e300c9ac4f0fd8d6ce5b7d7d60.tar.bz2
SimplifyCFG now predicts some conditional branches to true or false depending on previous branch on same comparison operands.
For example, if (a == b) { if (a > b) // this is false Fixes some of the issues on <rdar://problem/10554090> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146822 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index bf2cb49..d20e5a5 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "simplifycfg"
+#include "llvm/Transforms/Utils/CmpInstAnalysis.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
@@ -1702,6 +1703,47 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI) {
}
}
+ // Treat "if (cond1) { if (cond2) {} }" as "cond1 & cond2" and fold.
+ // This gives us the value of what cond2 is given cond1 is already known to
+ // be true.
+ if (ICmpInst *LHS = dyn_cast<ICmpInst>(PBI->getCondition())) {
+ if (ICmpInst *RHS = dyn_cast<ICmpInst>(BI->getCondition())) {
+ ICmpInst::Predicate LHSCC = LHS->getPredicate(),
+ RHSCC = RHS->getPredicate();
+ if (PredicatesFoldable(LHSCC, RHSCC)) {
+ if (LHS->getOperand(0) == RHS->getOperand(1) &&
+ LHS->getOperand(1) == RHS->getOperand(0))
+ LHS->swapOperands();
+ if (LHS->getOperand(0) == RHS->getOperand(0) &&
+ LHS->getOperand(1) == RHS->getOperand(1) &&
+ BB->getSinglePredecessor()) {
+ Value *Op0 = LHS->getOperand(0), *Op1 = LHS->getOperand(1);
+ bool CondIsTrue = PBI->getSuccessor(0) == BB;
+ unsigned LHSCode = getICmpCode(LHS, !CondIsTrue);
+ unsigned RHSCode = getICmpCode(RHS);
+ unsigned Code = LHSCode & RHSCode;
+
+ Value *ConstantCondition = NULL;
+ // If the resultant code is the same as the LHS code then as that
+ // code is known to be true we can make RHS now be true.
+ if (Code == LHSCode)
+ ConstantCondition = ConstantInt::get(
+ CmpInst::makeCmpResultType(LHS->getType()), 1);
+ else {
+ bool isSigned = LHS->isSigned() || RHS->isSigned();
+ CmpInst::Predicate IgnoredNewPred;
+ ConstantCondition = getICmpValue(isSigned, Code, Op0, Op1,
+ IgnoredNewPred);
+ }
+ if (ConstantCondition) {
+ RHS->replaceAllUsesWith(ConstantCondition);
+ return true;
+ }
+ }
+ }
+ }
+ }
+
// If this is a conditional branch in an empty block, and if any
// predecessors is a conditional branch to one of our destinations,
// fold the conditions into logical ops and one cond br.