Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -4389,9 +4389,9 @@ SmallPtrSet Visited; worklist.push_back(Addr); - // Use a worklist to iteratively look through PHI nodes, and ensure that - // the addressing mode obtained from the non-PHI roots of the graph - // are equivalent. + // Use a worklist to iteratively look through PHI and select nodes, and + // ensure that the addressing mode obtained from the non-PHI/select roots of + // the graph are equivalent. bool AddrModeFound = false; bool PhiSeen = false; SmallVector AddrModeInsts; @@ -4422,6 +4422,13 @@ PhiSeen = true; continue; } + // Similar for select. + if (SelectInst *SI = dyn_cast(V)) { + worklist.push_back(SI->getFalseValue()); + worklist.push_back(SI->getTrueValue()); + PhiSeen = true; + continue; + } // For non-PHIs, determine the addressing mode being computed. Note that // the result may differ depending on what other uses our candidate Index: test/Transforms/CodeGenPrepare/X86/sink-addrmode.ll =================================================================== --- test/Transforms/CodeGenPrepare/X86/sink-addrmode.ll +++ test/Transforms/CodeGenPrepare/X86/sink-addrmode.ll @@ -251,3 +251,20 @@ exit: ret void } + +; Make sure we can eliminate a select when both arguments perform equivalent +; address computation. +define void @test10(i1 %cond, i64* %base) { +; CHECK-LABEL: @test10 +; CHECK: getelementptr i8, {{.+}} 40 +; CHECK-NOT: select +entry: + %gep1 = getelementptr inbounds i64, i64* %base, i64 5 + %gep1.casted = bitcast i64* %gep1 to i32* + %base.casted = bitcast i64* %base to i32* + %gep2 = getelementptr inbounds i32, i32* %base.casted, i64 10 + %casted.merged = select i1 %cond, i32* %gep1.casted, i32* %gep2 + %v = load i32, i32* %casted.merged, align 4 + call void @foo(i32 %v) + ret void +}