Index: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp =================================================================== --- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -242,19 +242,26 @@ const auto *DeadII = dyn_cast(DeadI); if (KillingII == nullptr || DeadII == nullptr) return OW_Unknown; - if (KillingII->getIntrinsicID() != Intrinsic::masked_store || - DeadII->getIntrinsicID() != Intrinsic::masked_store) + // Only like type intrinsics... + if (KillingII->getIntrinsicID() != DeadII->getIntrinsicID()) return OW_Unknown; - // Pointers. - Value *KillingPtr = KillingII->getArgOperand(1)->stripPointerCasts(); - Value *DeadPtr = DeadII->getArgOperand(1)->stripPointerCasts(); - if (KillingPtr != DeadPtr && !AA.isMustAlias(KillingPtr, DeadPtr)) - return OW_Unknown; - // Masks. - // TODO: check that KillingII's mask is a superset of the DeadII's mask. - if (KillingII->getArgOperand(3) != DeadII->getArgOperand(3)) - return OW_Unknown; - return OW_Complete; + if (KillingII->getIntrinsicID() == Intrinsic::masked_store) { + // Types. + if (KillingII->getArgOperand(0)->getType() != + DeadII->getArgOperand(0)->getType()) + return OW_Unknown; + // Pointers. + Value *KillingPtr = KillingII->getArgOperand(1)->stripPointerCasts(); + Value *DeadPtr = DeadII->getArgOperand(1)->stripPointerCasts(); + if (KillingPtr != DeadPtr && !AA.isMustAlias(KillingPtr, DeadPtr)) + return OW_Unknown; + // Masks. + // TODO: check that KillingII's mask is a superset of the DeadII's mask. + if (KillingII->getArgOperand(3) != DeadII->getArgOperand(3)) + return OW_Unknown; + return OW_Complete; + } + return OW_Unknown; } /// Return 'OW_Complete' if a store to the 'KillingLoc' location completely Index: llvm/test/Transforms/DeadStoreElimination/masked-dead-store-no-merge.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/DeadStoreElimination/masked-dead-store-no-merge.ll @@ -0,0 +1,18 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -tbaa -dse -S < %s | FileCheck %s +target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048" + +define void @foo(ptr %a, <4 x i8> %v1, <4 x i32> %v2) { +; CHECK-LABEL: @foo( +; CHECK-NEXT: tail call void @llvm.masked.store.v4i32.p0(<4 x i32> [[V2:%.*]], ptr [[A:%.*]], i32 1, <4 x i1> ) +; CHECK-NEXT: tail call void @llvm.masked.store.v4i8.p0(<4 x i8> [[V1:%.*]], ptr [[A]], i32 1, <4 x i1> ) +; CHECK-NEXT: ret void +; + tail call void @llvm.masked.store.v4i32.p0(<4 x i32> %v2, ptr %a, i32 1, <4 x i1> ) + tail call void @llvm.masked.store.v4i8.p0(<4 x i8> %v1, ptr %a, i32 1, <4 x i1> ) + ret void +} + +declare void @llvm.masked.store.v4i8.p0(<4 x i8>, ptr, i32, <4 x i1>) +declare void @llvm.masked.store.v4i32.p0(<4 x i32>, ptr, i32, <4 x i1>) +