Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -2016,6 +2016,18 @@ if (isKnownNonNullFromDominatingCondition(V, Q.CxtI, Q.DT)) return true; + { + // Look through operations that do not alter the value. + if (const BitCastOperator *BCO = dyn_cast(V)) + return isKnownNonZero(BCO->getOperand(0), Depth, Q); + + if (const AddrSpaceCastInst *ASC = dyn_cast(V)) + return isKnownNonZero(ASC->getPointerOperand(), Depth, Q); + + if (const PtrToIntOperator *P2I = dyn_cast(V)) + return isKnownNonZero(P2I->getPointerOperand(), Depth, Q); + } + if (const GEPOperator *GEP = dyn_cast(V)) if (isGEPKnownNonNull(GEP, Depth, Q)) return true; Index: test/Transforms/InstCombine/alloca-cast-debuginfo.ll =================================================================== --- test/Transforms/InstCombine/alloca-cast-debuginfo.ll +++ test/Transforms/InstCombine/alloca-cast-debuginfo.ll @@ -45,7 +45,7 @@ ; Another dbg.value for "local" would be redundant here. ; CHECK-NOT: call void @llvm.dbg.value(metadata i8* [[simplified]], metadata !22, metadata !DIExpression()) ; -; CHECK: call void @escape(i8* [[simplified]]) +; CHECK: call void @escape(i8* nonnull [[simplified]]) ; CHECK: ret void declare void @llvm.dbg.declare(metadata, metadata, metadata) Index: test/Transforms/InstCombine/memcpy-from-global.ll =================================================================== --- test/Transforms/InstCombine/memcpy-from-global.ll +++ test/Transforms/InstCombine/memcpy-from-global.ll @@ -103,7 +103,7 @@ ; CHECK-NEXT: addrspacecast ; use @G instead of %A -; CHECK-NEXT: call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* align 4 %{{.*}}, +; CHECK-NEXT: call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* nonnull align 4 %{{.*}}, call void @llvm.memcpy.p1i8.p0i8.i64(i8 addrspace(1)* align 4 %a, i8* align 4 bitcast (%T* @G to i8*), i64 124, i1 false) call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* align 4 %b, i8 addrspace(1)* align 4 %a, i64 124, i1 false) call void @bar_as1(i8 addrspace(1)* %b) Index: test/Transforms/InstCombine/objsize.ll =================================================================== --- test/Transforms/InstCombine/objsize.ll +++ test/Transforms/InstCombine/objsize.ll @@ -114,7 +114,7 @@ %1 = bitcast %struct.data* %0 to i8* %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false, i1 false) nounwind ; CHECK-NOT: @llvm.objectsize -; CHECK: @llvm.memset.p0i8.i32(i8* align 8 %1, i8 0, i32 1824, i1 false) +; CHECK: @llvm.memset.p0i8.i32(i8* nonnull align 8 %1, i8 0, i32 1824, i1 false) %3 = call i8* @__memset_chk(i8* %1, i32 0, i32 1824, i32 %2) nounwind store i8* %1, i8** %esc ret i32 0 Index: test/Transforms/InstCombine/select.ll =================================================================== --- test/Transforms/InstCombine/select.ll +++ test/Transforms/InstCombine/select.ll @@ -1141,7 +1141,7 @@ ; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4 ; CHECK-NEXT: [[X1:%.*]] = bitcast float* [[X]] to i32* ; CHECK-NEXT: [[Y1:%.*]] = bitcast i32* [[Y]] to float* -; CHECK-NEXT: call void @scribble_on_i32(i32* [[X1]]) +; CHECK-NEXT: call void @scribble_on_i32(i32* nonnull [[X1]]) ; CHECK-NEXT: call void @scribble_on_i32(i32* nonnull [[Y]]) ; CHECK-NEXT: [[TMP:%.*]] = load float, float* [[X]], align 4 ; CHECK-NEXT: store float [[TMP]], float* [[Y1]], align 4 @@ -1172,8 +1172,8 @@ ; CHECK-NEXT: [[Y:%.*]] = alloca i8*, align 8 ; CHECK-NEXT: [[TMPCAST:%.*]] = bitcast i8** [[Y]] to i64* ; CHECK-NEXT: [[X1:%.*]] = bitcast i8** [[X]] to i64* -; CHECK-NEXT: call void @scribble_on_i64(i64* [[X1]]) -; CHECK-NEXT: call void @scribble_on_i64(i64* [[TMPCAST]]) +; CHECK-NEXT: call void @scribble_on_i64(i64* nonnull [[X1]]) +; CHECK-NEXT: call void @scribble_on_i64(i64* nonnull [[TMPCAST]]) ; CHECK-NEXT: [[TMP:%.*]] = load i64, i64* [[X1]], align 8 ; CHECK-NEXT: store i64 [[TMP]], i64* [[TMPCAST]], align 8 ; CHECK-NEXT: [[V:%.*]] = inttoptr i64 [[TMP]] to i8* @@ -1200,8 +1200,8 @@ ; CHECK-NEXT: [[Y:%.*]] = alloca i8*, align 8 ; CHECK-NEXT: [[TMPCAST:%.*]] = bitcast i8** [[Y]] to i64* ; CHECK-NEXT: [[X1:%.*]] = bitcast i8** [[X]] to i64* -; CHECK-NEXT: call void @scribble_on_i64(i64* [[X1]]) -; CHECK-NEXT: call void @scribble_on_i64(i64* [[TMPCAST]]) +; CHECK-NEXT: call void @scribble_on_i64(i64* nonnull [[X1]]) +; CHECK-NEXT: call void @scribble_on_i64(i64* nonnull [[TMPCAST]]) ; CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X]], align 8 ; CHECK-NEXT: store i8* [[TMP]], i8** [[Y]], align 8 ; CHECK-NEXT: [[V:%.*]] = ptrtoint i8* [[TMP]] to i64 @@ -1230,7 +1230,7 @@ ; CHECK-NEXT: [[X1_SUB:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[X1]], i64 0, i64 0 ; CHECK-NEXT: [[X2:%.*]] = bitcast [2 x i8*]* [[X1]] to i128* ; CHECK-NEXT: [[Y1:%.*]] = bitcast i128* [[Y]] to i8** -; CHECK-NEXT: call void @scribble_on_i128(i128* [[X2]]) +; CHECK-NEXT: call void @scribble_on_i128(i128* nonnull [[X2]]) ; CHECK-NEXT: call void @scribble_on_i128(i128* nonnull [[Y]]) ; CHECK-NEXT: [[TMP:%.*]] = load i128, i128* [[X2]], align 8 ; CHECK-NEXT: store i128 [[TMP]], i128* [[Y]], align 8 @@ -1263,7 +1263,7 @@ ; CHECK-NEXT: [[X1_SUB:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[X1]], i64 0, i64 0 ; CHECK-NEXT: [[X2:%.*]] = bitcast [2 x i8*]* [[X1]] to i128* ; CHECK-NEXT: [[Y1:%.*]] = bitcast i128* [[Y]] to i8** -; CHECK-NEXT: call void @scribble_on_i128(i128* [[X2]]) +; CHECK-NEXT: call void @scribble_on_i128(i128* nonnull [[X2]]) ; CHECK-NEXT: call void @scribble_on_i128(i128* nonnull [[Y]]) ; CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X1_SUB]], align 8 ; CHECK-NEXT: store i8* [[TMP]], i8** [[Y1]], align 8