diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 9 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/sunkaddr-ext.ll | 26 |
2 files changed, 34 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), diff --git a/llvm/test/CodeGen/X86/sunkaddr-ext.ll b/llvm/test/CodeGen/X86/sunkaddr-ext.ll new file mode 100644 index 00000000000..6d238678ce3 --- /dev/null +++ b/llvm/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 |

