summaryrefslogtreecommitdiff
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
commit489752ddb4ba90a9baf433b449fcc753eb6a23d7 (patch)
treef76834270cae5a6391666c3d2563e874cd2f2ef9
parentb82f8a28e8768d1acdb565adbda9ac8b241471a9 (diff)
downloadllvm-489752ddb4ba90a9baf433b449fcc753eb6a23d7.tar.gz
llvm-489752ddb4ba90a9baf433b449fcc753eb6a23d7.tar.bz2
llvm-489752ddb4ba90a9baf433b449fcc753eb6a23d7.tar.xz
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204833 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CodeGenPrepare.cpp9
-rw-r--r--test/CodeGen/X86/sunkaddr-ext.ll26
2 files changed, 34 insertions, 1 deletions
diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp
index 428d8af359..a3961e8003 100644
--- a/lib/CodeGen/CodeGenPrepare.cpp
+++ b/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),
diff --git a/test/CodeGen/X86/sunkaddr-ext.ll b/test/CodeGen/X86/sunkaddr-ext.ll
new file mode 100644
index 0000000000..6d238678ce
--- /dev/null
+++ b/test/CodeGen/X86/sunkaddr-ext.ll
@@ -0,0 +1,26 @@
+; RUN: llc < %s | FileCheck %s
+
+; Test to make sure that if math that can roll over has been used we don't
+; use the potential overflow as the basis for an address calculation later by
+; sinking it into a different basic block.
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.9.0"
+
+; Function Attrs: nounwind ssp uwtable
+define void @test_sink(i8* %arg1, i32 %arg2, i8 %arg3) #0 {
+ %tmp1 = add i32 -2147483648, %arg2
+ %tmp2 = add i32 -2147483648, %tmp1
+ %tmp3 = getelementptr i8* %arg1, i32 %arg2
+ br label %bb1
+
+bb1:
+ %tmp4 = getelementptr i8* %arg1, i32 %tmp2
+ store i8 %arg3, i8* %tmp4
+ ret void;
+}
+
+; CHECK-LABEL: test_sink:
+; CHECK: movslq %esi, [[TEMP:%[a-z0-9]+]]
+; CHECK: movb %dl, (%rdi,[[TEMP]])
+; CHECK: retq