Index: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp +++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp @@ -761,12 +761,13 @@ continue; } - // If this instruction may read from memory, forget LastStore. - // Load/store intrinsics will indicate both a read and a write to - // memory. The target may override this (e.g. so that a store intrinsic - // does not read from memory, and thus will be treated the same as a - // regular store for commoning purposes). - if (Inst->mayReadFromMemory() && + // If this instruction may read from memory or throw (and potentially read + // from memory in the exception handler), forget LastStore. Load/store + // intrinsics will indicate both a read and a write to memory. The target + // may override this (e.g. so that a store intrinsic does not read from + // memory, and thus will be treated the same as a regular store for + // commoning purposes). + if ((Inst->mayReadFromMemory() || Inst->mayThrow()) && !(MemInst.isValid() && !MemInst.mayReadFromMemory())) LastStore = nullptr; Index: llvm/trunk/test/Transforms/EarlyCSE/readnone-mayunwind.ll =================================================================== --- llvm/trunk/test/Transforms/EarlyCSE/readnone-mayunwind.ll +++ llvm/trunk/test/Transforms/EarlyCSE/readnone-mayunwind.ll @@ -0,0 +1,15 @@ +; RUN: opt -S -early-cse < %s | FileCheck %s + +declare void @readnone_may_unwind() readnone + +define void @f(i32* %ptr) { +; CHECK-LABEL: @f( +; CHECK: store i32 100, i32* %ptr +; CHECK: call void @readnone_may_unwind() +; CHECK: store i32 200, i32* %ptr + + store i32 100, i32* %ptr + call void @readnone_may_unwind() + store i32 200, i32* %ptr + ret void +}