diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp --- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp +++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp @@ -1366,8 +1366,13 @@ LLVM_DEBUG(dbgs() << "Skipping due to debug counter\n"); continue; } - if (auto *I = dyn_cast(V)) - I->andIRFlags(&Inst); + if (auto *I = dyn_cast(V)) { + if (programUndefinedIfPoison(I)) { + // Keep poison generating flags, if I being poison is UB. + I->andNonPoisonGeneratingIRFlags(&Inst); + } else + I->andIRFlags(&Inst); + } Inst.replaceAllUsesWith(V); salvageKnowledge(&Inst, &AC); removeMSSA(Inst); diff --git a/llvm/test/Transforms/EarlyCSE/flags.ll b/llvm/test/Transforms/EarlyCSE/flags.ll --- a/llvm/test/Transforms/EarlyCSE/flags.ll +++ b/llvm/test/Transforms/EarlyCSE/flags.ll @@ -22,7 +22,7 @@ define void @test_inbounds_program_ub_if_first_gep_poison(i8* %ptr, i64 %n) { ; CHECK-LABEL: @test_inbounds_program_ub_if_first_gep_poison( -; CHECK-NEXT: [[ADD_PTR_1:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i64 [[N:%.*]] +; CHECK-NEXT: [[ADD_PTR_1:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 [[N:%.*]] ; CHECK-NEXT: call void @use.i8(i8* noundef [[ADD_PTR_1]]) ; CHECK-NEXT: call void @use.i8(i8* [[ADD_PTR_1]]) ; CHECK-NEXT: ret void