summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2014-03-26 17:27:01 +0000
committerJim Grosbach <grosbach@apple.com>2014-03-26 17:27:01 +0000
commited2cd39b81d09c424217dcf60917a059379cc867 (patch)
tree0ac21cb4afac29f7fa8f1a89b6831bad6d3d6bc3 /llvm/lib
parent6b33c6f2349f74f0a70d5447e2c3eb0913aba902 (diff)
downloadbcm5719-llvm-ed2cd39b81d09c424217dcf60917a059379cc867.tar.gz
bcm5719-llvm-ed2cd39b81d09c424217dcf60917a059379cc867.zip
Fix for incorrect address sinking in the presence of potential overflows.
In some cases it is possible for CGP to attempt to reuse a base address from another basic block. In those cases we have to be sure that all the address math was either done at the same bit width, or that none of it overflowed before it was extended. Patch by Louis Gerbarg <lgg@apple.com> rdar://16307442 llvm-svn: 204833
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 428d8af359e..a3961e80031 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -2438,7 +2438,14 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
cast<IntegerType>(V->getType())->getBitWidth()) {
V = Builder.CreateTrunc(V, IntPtrTy, "sunkaddr");
} else {
- V = Builder.CreateSExt(V, IntPtrTy, "sunkaddr");
+ // It is only safe to sign extend the BaseReg if we know that the math
+ // required to create it did not overflow before we extend it. Since
+ // the original IR value was tossed in favor of a constant back when
+ // the AddrMode was created we need to bail out gracefully if widths
+ // do not match instead of extending it.
+ if (Result != AddrMode.BaseReg)
+ cast<Instruction>(Result)->eraseFromParent();
+ return false;
}
if (AddrMode.Scale != 1)
V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy, AddrMode.Scale),
OpenPOWER on IntegriCloud