diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -72,14 +72,14 @@ continue; } - if (isa(I)) { + if (isa(I)) { // We set IsOffset=true, to forbid the memcpy from occurring after the // phi: If one of the phi operands is not based on the alloca, we // would incorrectly omit a write. Worklist.emplace_back(I, true); continue; } - if (isa(I) || isa(I)) { + if (isa(I)) { // If uses of the bitcast are ok, we are ok. Worklist.emplace_back(I, IsOffset); continue; @@ -320,6 +320,19 @@ Worklist.insert(PHI); if (!collectUsersRecursive(*PHI)) return false; + } else if (auto *SI = dyn_cast(Inst)) { + if (!isa(SI->getTrueValue()) || + !isa(SI->getFalseValue())) + return false; + + if (!isAvailable(cast(SI->getTrueValue())) || + !isAvailable(cast(SI->getFalseValue()))) { + ValuesToRevisit.insert(Inst); + continue; + } + Worklist.insert(SI); + if (!collectUsersRecursive(*SI)) + return false; } else if (isa(Inst)) { Worklist.insert(Inst); if (!collectUsersRecursive(*Inst)) @@ -385,6 +398,13 @@ IC.InsertNewInstWith(NewI, *BC); NewI->takeName(BC); WorkMap[BC] = NewI; + } else if (auto *SI = dyn_cast(I)) { + auto *NewSI = SelectInst::Create( + SI->getCondition(), getReplacement(SI->getTrueValue()), + getReplacement(SI->getFalseValue()), SI->getName(), nullptr, SI); + IC.InsertNewInstWith(NewSI, *SI); + NewSI->takeName(SI); + WorkMap[SI] = NewSI; } else if (auto *MemCpy = dyn_cast(I)) { auto *SrcV = getReplacement(MemCpy->getRawSource()); // The pointer may appear in the destination of a copy, but we don't want to diff --git a/llvm/test/Transforms/InstCombine/ptr-replace-alloca.ll b/llvm/test/Transforms/InstCombine/ptr-replace-alloca.ll --- a/llvm/test/Transforms/InstCombine/ptr-replace-alloca.ll +++ b/llvm/test/Transforms/InstCombine/ptr-replace-alloca.ll @@ -366,9 +366,7 @@ define i8 @select_same_addrspace_remove_alloca(i1 %cond, ptr %p) { ; CHECK-LABEL: @select_same_addrspace_remove_alloca( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 1 -; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(32) [[ALLOCA]], ptr noundef nonnull align 16 dereferenceable(32) @g1, i64 32, i1 false) -; CHECK-NEXT: [[PTR:%.*]] = select i1 [[COND:%.*]], ptr [[ALLOCA]], ptr [[P:%.*]] +; CHECK-NEXT: [[PTR:%.*]] = select i1 [[COND:%.*]], ptr @g1, ptr [[P:%.*]] ; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr [[PTR]], align 1 ; CHECK-NEXT: ret i8 [[LOAD]] ; @@ -417,13 +415,8 @@ define i8 @select_diff_addrspace_remove_alloca(i1 %cond, ptr %p) { ; CHECK-LABEL: @select_diff_addrspace_remove_alloca( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 1 -; CHECK-NEXT: call void @llvm.memcpy.p0.p1.i64(ptr noundef nonnull align 1 dereferenceable(32) [[ALLOCA]], ptr addrspace(1) noundef align 16 dereferenceable(32) @g2, i64 32, i1 false) -; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [32 x i8], ptr [[ALLOCA]], i64 0, i64 2 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], ptr [[ALLOCA]], ptr [[GEP]] -; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[SEL]], i64 4 -; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr [[GEP2]], align 1 -; CHECK-NEXT: ret i8 [[LOAD]] +; CHECK-NOT: [[ALLOCA:%.*]] = alloca [32 x i8] +; CHECK-NEXT: ret i8 0 ; entry: %alloca = alloca [32 x i8]