diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 0603b9feaa860..45f1b543b8fc7 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1127,6 +1127,12 @@ const SCEV *ScalarEvolution::getLosslessPtrToIntExpr(const SCEV *Op) { const SCEV *ScalarEvolution::getPtrToAddrExpr(const SCEV *Op) { assert(Op->getType()->isPointerTy() && "Op must be a pointer"); + + // Treat pointers with unstable representation conservatively, since the + // address bits may change. + if (DL.hasUnstableRepresentation(Op->getType())) + return getCouldNotCompute(); + Type *Ty = DL.getAddressType(Op->getType()); // Use the rewriter to sink the cast down to SCEVUnknown leaves. @@ -8175,8 +8181,12 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) { return getSCEV(U->getOperand(0)); break; - case Instruction::PtrToAddr: - return getPtrToAddrExpr(getSCEV(U->getOperand(0))); + case Instruction::PtrToAddr: { + const SCEV *IntOp = getPtrToAddrExpr(getSCEV(U->getOperand(0))); + if (isa(IntOp)) + return getUnknown(V); + return IntOp; + } case Instruction::PtrToInt: { // Pointer to integer cast is straight-forward, so do model it. diff --git a/llvm/test/Analysis/ScalarEvolution/ptrtoaddr.ll b/llvm/test/Analysis/ScalarEvolution/ptrtoaddr.ll index 2de02b8a319e0..82b8302db7cfd 100644 --- a/llvm/test/Analysis/ScalarEvolution/ptrtoaddr.ll +++ b/llvm/test/Analysis/ScalarEvolution/ptrtoaddr.ll @@ -89,13 +89,12 @@ define void @ptrtoaddr_of_gep_with_unknown_int(ptr %in, ptr %out0, ptr %offset) ret void } -; FIXME: Currently not handled correctly. ; ptrtoaddr of a pointer with unstable representation should return SCEVUnknown. define void @ptrtoaddr_unstable(ptr addrspace(2) %in, ptr %out) { ; CHECK-LABEL: 'ptrtoaddr_unstable' ; CHECK-NEXT: Classifying expressions for: @ptrtoaddr_unstable ; CHECK-NEXT: %p = ptrtoaddr ptr addrspace(2) %in to i64 -; CHECK-NEXT: --> (ptrtoaddr ptr addrspace(2) %in to i64) U: full-set S: full-set +; CHECK-NEXT: --> %p U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @ptrtoaddr_unstable ; %p = ptrtoaddr ptr addrspace(2) %in to i64 @@ -103,7 +102,6 @@ define void @ptrtoaddr_unstable(ptr addrspace(2) %in, ptr %out) { ret void } -; FIXME: Currently not handled correctly. ; ptrtoaddr of GEP on unstable pointer should return SCEVUnknown. define void @ptrtoaddr_unstable_gep(ptr addrspace(2) %in, ptr %out) { ; CHECK-LABEL: 'ptrtoaddr_unstable_gep' @@ -111,7 +109,7 @@ define void @ptrtoaddr_unstable_gep(ptr addrspace(2) %in, ptr %out) { ; CHECK-NEXT: %gep = getelementptr inbounds i8, ptr addrspace(2) %in, i64 42 ; CHECK-NEXT: --> (42 + %in) U: full-set S: full-set ; CHECK-NEXT: %p = ptrtoaddr ptr addrspace(2) %gep to i64 -; CHECK-NEXT: --> (42 + (ptrtoaddr ptr addrspace(2) %in to i64)) U: full-set S: full-set +; CHECK-NEXT: --> %p U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @ptrtoaddr_unstable_gep ; %gep = getelementptr inbounds i8, ptr addrspace(2) %in, i64 42 @@ -120,13 +118,12 @@ define void @ptrtoaddr_unstable_gep(ptr addrspace(2) %in, ptr %out) { ret void } -; FIXME: Currently not handled correctly. ; ptrtoaddr of nullptr in unstable address space should return SCEVUnknown. define void @ptrtoaddr_unstable_null(ptr %out) { ; CHECK-LABEL: 'ptrtoaddr_unstable_null' ; CHECK-NEXT: Classifying expressions for: @ptrtoaddr_unstable_null ; CHECK-NEXT: %p = ptrtoaddr ptr addrspace(2) null to i64 -; CHECK-NEXT: --> 0 U: [0,1) S: [0,1) +; CHECK-NEXT: --> %p U: [0,1) S: [0,1) ; CHECK-NEXT: Determining loop execution counts for: @ptrtoaddr_unstable_null ; %p = ptrtoaddr ptr addrspace(2) null to i64