Index: llvm/lib/Analysis/LoopAccessAnalysis.cpp =================================================================== --- llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -1492,6 +1492,9 @@ LLVM_DEBUG(dbgs() << "LAA: Distance for " << *InstMap[AIdx] << " to " << *InstMap[BIdx] << ": " << *Dist << "\n"); + if (isa(Dist)) + return Dependence::Unknown; + // Need accesses with constant stride. We don't want to vectorize // "A[B[i]] += ..." and similar code or pointer arithmetic that could wrap in // the address space. Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -4085,6 +4085,16 @@ if (LHS == RHS) return getZero(LHS->getType()); + // Pointer subtraction when LHS and RHS are based on different objects is + // not well defined. For integral pointers, we fall back to inttoptrs + // but we don't have that option for non-integral pointers. Note that + // subtracting an offset from a non-integral pointer is fine. + // TODO: If we had an actual pointer subtraction primitive which didn't + // require ptrtoint, we could get better results for non-integral pointers + // here. + if (getDataLayout().isNonIntegralPointerType(RHS->getType())) + return getCouldNotCompute(); + // We represent LHS - RHS as LHS + (-1)*RHS. This transformation // makes it so that we cannot make much use of NUW. auto AddFlags = SCEV::FlagAnyWrap; Index: llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-ni.ll =================================================================== --- llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-ni.ll +++ llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-ni.ll @@ -12,20 +12,15 @@ declare i64 @julia_steprange_last_4949() +@G = external global i32 + define void @"japi1_align!_9477"(%jl_value_t addrspace(10)** %arg) { ; LV-LAVEL: L26.lver.check -; LV: [[OFMul:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[Step:%[^ ]*]]) -; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul]], 0 -; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul]], 1 -; LV-NEXT: [[PosGEP:%[^ ]*]] = getelementptr i32, i32 addrspace(13)* [[Base:%[^ ]*]], i64 [[Step]] -; LV-NEXT: [[NegGEP:%[^ ]*]] = getelementptr i32, i32 addrspace(13)* [[Base]], i64 [[NegStep:%[^ ]*]] -; LV-NEXT: icmp ugt i32 addrspace(13)* [[NegGEP]], [[Base]] -; LV-NEXT: icmp ult i32 addrspace(13)* [[PosGEP]], [[Base]] ; LV-NOT: inttoptr ; LV-NOT: ptrtoint top: %tmp = load %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %arg, align 8 - %tmp1 = load i32, i32* inttoptr (i64 12 to i32*), align 4 + %tmp1 = load i32, i32* @G, align 4 %tmp2 = sub i32 0, %tmp1 %tmp3 = call i64 @julia_steprange_last_4949() %tmp4 = addrspacecast %jl_value_t addrspace(10)* %tmp to %jl_value_t addrspace(11)*