diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -194,7 +194,14 @@ } // All constant incoming values map to the same variable along the incoming - // edges of the phi. The phi is unnecessary. + // edges of the phi. The phi is unnecessary. However, we must drop all + // poison-generating flags to ensure that no poison is propagated to the phi + // location by performing this substitution. + // Warning: If the underlying analysis changes, this may not be enough to + // guarantee that poison is not propagated. + // TODO: We may be able to re-infer flags by re-analyzing the instruction. + if (auto *CommonInst = dyn_cast(CommonValue)) + CommonInst->dropPoisonGeneratingFlags(); P->replaceAllUsesWith(CommonValue); P->eraseFromParent(); ++NumPhiCommon; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/phi-common-val.ll b/llvm/test/Transforms/CorrelatedValuePropagation/phi-common-val.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/phi-common-val.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/phi-common-val.ll @@ -123,14 +123,13 @@ ret i8* %r } -; FIXME: ; The sub has 'nsw', so it is not safe to propagate that value along ; the bb2 edge because that would propagate poison to the return. define i32 @PR43802(i32 %arg) { ; CHECK-LABEL: @PR43802( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[ARG:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[ARG:%.*]] ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ARG]], -2147483648 ; CHECK-NEXT: br i1 [[CMP]], label [[BB2:%.*]], label [[BB3:%.*]] ; CHECK: bb2: