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 @@ -781,6 +781,21 @@ return getLoadStorePointerOperand(Inst); } + Type *getValueType() const { + // TODO: handle target-specific intrinsics. + if (IntrinsicInst *II = dyn_cast(Inst)) { + switch (II->getIntrinsicID()) { + case Intrinsic::masked_load: + return II->getType(); + case Intrinsic::masked_store: + return II->getArgOperand(0)->getType(); + default: + return nullptr; + } + } + return getLoadStoreType(Inst); + } + bool mayReadFromMemory() const { if (IntrID != 0) return Info.ReadMem; @@ -1162,6 +1177,9 @@ "Violated invariant"); if (Earlier.getPointerOperand() != Later.getPointerOperand()) return false; + if (!Earlier.getValueType() || !Later.getValueType() || + Earlier.getValueType() != Later.getValueType()) + return false; if (Earlier.getMatchingId() != Later.getMatchingId()) return false; // At the moment, we don't remove ordered stores, but do remove diff --git a/llvm/test/Transforms/EarlyCSE/opaque-ptr.ll b/llvm/test/Transforms/EarlyCSE/opaque-ptr.ll --- a/llvm/test/Transforms/EarlyCSE/opaque-ptr.ll +++ b/llvm/test/Transforms/EarlyCSE/opaque-ptr.ll @@ -30,3 +30,14 @@ %sub = sub i32 %a, %v2.c ret i32 %sub } + +define void @dse(ptr %p, i32 %i1, i8 %i2) { +; CHECK-LABEL: @dse( +; CHECK-NEXT: store i32 [[I1:%.*]], ptr [[P:%.*]], align 4 +; CHECK-NEXT: store i8 [[I2:%.*]], ptr [[P]], align 1 +; CHECK-NEXT: ret void +; + store i32 %i1, ptr %p + store i8 %i2, ptr %p + ret void +}