diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp --- a/llvm/lib/Analysis/CaptureTracking.cpp +++ b/llvm/lib/Analysis/CaptureTracking.cpp @@ -424,6 +424,11 @@ auto *LI = dyn_cast(I->getOperand(OtherIdx)); if (LI && isa(LI->getPointerOperand())) return UseCaptureKind::NO_CAPTURE; + if (auto *CE = dyn_cast(I->getOperand(OtherIdx))) { + if (CE->getOpcode() == Instruction::GetElementPtr && + isa(CE->getOperand(0))) + return UseCaptureKind::NO_CAPTURE; + } // Otherwise, be conservative. There are crazy ways to capture pointers // using comparisons. return UseCaptureKind::MAY_CAPTURE; diff --git a/llvm/test/Transforms/DeadStoreElimination/const-expr.ll b/llvm/test/Transforms/DeadStoreElimination/const-expr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/DeadStoreElimination/const-expr.ll @@ -0,0 +1,18 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -passes=dse -S < %s | FileCheck %s +@global = external constant [4 x i8] + +define internal void @f() { +; CHECK-LABEL: @f( +; CHECK-NEXT: [[TMP1:%.*]] = call noalias i8* @_Znwm(i64 32) +; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i8* [[TMP1]], getelementptr inbounds ([4 x i8], [4 x i8]* @global, i64 0, i64 0) +; CHECK-NEXT: ret void +; + %tmp1 = call noalias i8* @_Znwm(i64 32) + %tmp2 = icmp ugt i8* %tmp1, getelementptr inbounds ([4 x i8], [4 x i8]* @global, i64 0, i64 0) + %tmp3 = getelementptr inbounds i8, i8* %tmp1, i64 3 + store i8 0, i8* %tmp3 + ret void +} + +declare i8* @_Znwm(i64)