Index: lib/Transforms/Scalar/Sink.cpp =================================================================== --- lib/Transforms/Scalar/Sink.cpp +++ lib/Transforms/Scalar/Sink.cpp @@ -114,7 +114,7 @@ if (SuccToSinkTo->getUniquePredecessor() != Inst->getParent()) { // We cannot sink a load across a critical edge - there may be stores in // other code paths. - if (isa(Inst)) + if (Inst->mayReadFromMemory()) return false; // We don't want to sink across a critical edge if we don't dominate the Index: test/Transforms/Sink/badloadsink.ll =================================================================== --- test/Transforms/Sink/badloadsink.ll +++ 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 0) + %y2 = ptrtoint i8* %y to i64 + %retval = add i64 %y2, %x + ret i64 %retval } +