Index: lib/IR/Value.cpp =================================================================== --- lib/IR/Value.cpp +++ lib/IR/Value.cpp @@ -23,8 +23,10 @@ #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/Statepoint.h" #include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/Debug.h" @@ -570,6 +572,13 @@ return true; } + // For gc.relocate, look through relocations + if (const IntrinsicInst *I = dyn_cast(V)) + if (I->getIntrinsicID() == Intrinsic::experimental_gc_relocate) { + GCRelocateOperands RelocateInst(I); + return isDereferenceablePointer(RelocateInst.derivedPtr(), DL, Visited); + } + if (const AddrSpaceCastInst *ASC = dyn_cast(V)) return isDereferenceablePointer(ASC->getOperand(0), DL, Visited); Index: test/Analysis/ValueTracking/memory-dereferenceable.ll =================================================================== --- test/Analysis/ValueTracking/memory-dereferenceable.ll +++ test/Analysis/ValueTracking/memory-dereferenceable.ll @@ -12,8 +12,7 @@ ; CHECK: %globalptr ; CHECK: %alloca ; CHECK: %dparam -; We haven't yet taught it to look through relocations -; CHECK-NOT: %relocate +; CHECK: %relocate ; CHECK-NOT: %nparam entry: %globalptr = getelementptr inbounds [6 x i8]* @globalstr, i32 0, i32 0