aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2014-07-25 21:13:35 +0000
committerHal Finkel <hfinkel@anl.gov>2014-07-25 21:13:35 +0000
commit930469107d34d66b015f6e48b3f05554819216d8 (patch)
tree3d23c9a2e9b5241703cbcfcc6040619ea65894d1 /llvm/lib/Transforms/Utils/Local.cpp
parentc888757a2dcaf365a115cd250da045e12af013c1 (diff)
downloadllvm-930469107d34d66b015f6e48b3f05554819216d8.zip
llvm-930469107d34d66b015f6e48b3f05554819216d8.tar.gz
llvm-930469107d34d66b015f6e48b3f05554819216d8.tar.bz2
Add @llvm.assume, lowering, and some basic properties
This is the first commit in a series that add an @llvm.assume intrinsic which can be used to provide the optimizer with a condition it may assume to be true (when the control flow would hit the intrinsic call). Some basic properties are added here: - llvm.invariant(true) is dead. - llvm.invariant(false) is unreachable (this directly corresponds to the documented behavior of MSVC's __assume(0)), so is llvm.invariant(undef). The intrinsic is tagged as writing arbitrarily, in order to maintain control dependencies. BasicAA has been updated, however, to return NoModRef for any particular location-based query so that we don't unnecessarily block code motion. llvm-svn: 213973
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index a5e443f..d891fc0 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -301,6 +301,14 @@ bool llvm::isInstructionTriviallyDead(Instruction *I,
if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end)
return isa<UndefValue>(II->getArgOperand(1));
+
+ // Assumptions are dead if their condition is trivially true.
+ if (II->getIntrinsicID() == Intrinsic::assume) {
+ if (ConstantInt *Cond = dyn_cast<ConstantInt>(II->getArgOperand(0)))
+ return !Cond->isZero();
+
+ return false;
+ }
}
if (isAllocLikeFn(I, TLI)) return true;
@@ -1183,6 +1191,26 @@ static bool markAliveBlocks(BasicBlock *BB,
// instructions into LLVM unreachable insts. The instruction combining pass
// canonicalizes unreachable insts into stores to null or undef.
for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E;++BBI){
+ // Assumptions that are known to be false are equivalent to unreachable.
+ // Also, if the condition is undefined, then we make the choice most
+ // beneficial to the optimizer, and choose that to also be unreachable.
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(BBI))
+ if (II->getIntrinsicID() == Intrinsic::assume) {
+ bool MakeUnreachable = false;
+ if (isa<UndefValue>(II->getArgOperand(0)))
+ MakeUnreachable = true;
+ else if (ConstantInt *Cond =
+ dyn_cast<ConstantInt>(II->getArgOperand(0)))
+ MakeUnreachable = Cond->isZero();
+
+ if (MakeUnreachable) {
+ // Don't insert a call to llvm.trap right before the unreachable.
+ changeToUnreachable(BBI, false);
+ Changed = true;
+ break;
+ }
+ }
+
if (CallInst *CI = dyn_cast<CallInst>(BBI)) {
if (CI->doesNotReturn()) {
// If we found a call to a no-return function, insert an unreachable