diff options
-rw-r--r-- | llvm/lib/Transforms/Scalar/Sink.cpp | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/Sink/badloadsink.ll | 12 |
2 files changed, 11 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/Sink.cpp b/llvm/lib/Transforms/Scalar/Sink.cpp index cfb8a062299..81176288049 100644 --- a/llvm/lib/Transforms/Scalar/Sink.cpp +++ b/llvm/lib/Transforms/Scalar/Sink.cpp @@ -114,7 +114,7 @@ static bool IsAcceptableTarget(Instruction *Inst, BasicBlock *SuccToSinkTo, if (SuccToSinkTo->getUniquePredecessor() != Inst->getParent()) { // We cannot sink a load across a critical edge - there may be stores in // other code paths. - if (isa<LoadInst>(Inst)) + if (Inst->mayReadFromMemory()) return false; // We don't want to sink across a critical edge if we don't dominate the diff --git a/llvm/test/Transforms/Sink/badloadsink.ll b/llvm/test/Transforms/Sink/badloadsink.ll index e3f4884c5a4..eb2b0fae482 100644 --- a/llvm/test/Transforms/Sink/badloadsink.ll +++ b/llvm/test/Transforms/Sink/badloadsink.ll @@ -1,18 +1,26 @@ ; RUN: opt < %s -basicaa -sink -S | FileCheck %s declare void @foo(i64 *) -define i64 @sinkload(i1 %cmp) { +declare i8* @llvm.load.relative.i32(i8* %ptr, i32 %offset) argmemonly nounwind readonly +define i64 @sinkload(i1 %cmp, i8* %ptr, i32 %off) { ; CHECK-LABEL: @sinkload top: %a = alloca i64 ; CHECK: call void @foo(i64* %a) ; CHECK-NEXT: %x = load i64, i64* %a +; CHECK-NEXT: %y = call i8* @llvm.load.relative.i32(i8* %ptr, i32 %off) call void @foo(i64* %a) %x = load i64, i64* %a + %y = call i8* @llvm.load.relative.i32(i8* %ptr, i32 %off) br i1 %cmp, label %A, label %B A: store i64 0, i64 *%a + store i8 0, i8 *%ptr br label %B B: ; CHECK-NOT: load i64, i64 *%a - ret i64 %x +; CHECK-NOT: call i8* @llvm.load.relative(i8* %ptr, i32 off) + %y2 = ptrtoint i8* %y to i64 + %retval = add i64 %y2, %x + ret i64 %retval } + |