Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -2694,26 +2694,32 @@ else if (DifferentField != ThisDifferentField) DifferentField = ExtAddrMode::MultipleFields; - // If NewAddrMode differs in only one dimension, and that dimension isn't - // the amount that ScaledReg is scaled by, then we can handle it by - // inserting a phi/select later on. Even if NewAddMode is the same - // we still need to collect it due to original value is different. - // And later we will need all original values as anchors during - // finding the common Phi node. + // If NewAddrMode differs in more than one dimension we cannot handle it. + bool CanHandle = DifferentField != ExtAddrMode::MultipleFields; + + // If Scale Field is different then we reject. + CanHandle = CanHandle && DifferentField != ExtAddrMode::ScaleField; + // We also must reject the case when base offset is different and // scale reg is not null, we cannot handle this case due to merge of // different offsets will be used as ScaleReg. - if (DifferentField != ExtAddrMode::MultipleFields && - DifferentField != ExtAddrMode::ScaleField && - (DifferentField != ExtAddrMode::BaseOffsField || - !NewAddrMode.ScaledReg)) { + CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField || + !NewAddrMode.ScaledReg); + + // We also must reject the case when GV is different and BaseReg installed + // due to we want to use base reg as a merge of GV values. + CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseGVField || + !NewAddrMode.HasBaseReg); + + // Even if NewAddMode is the same we still need to collect it due to + // original value is different. And later we will need all original values + // as anchors during finding the common Phi node. + if (CanHandle) AddrModes.emplace_back(NewAddrMode); - return true; - } + else + AddrModes.clear(); - // We couldn't combine NewAddrMode with the rest, so return failure. - AddrModes.clear(); - return false; + return CanHandle; } /// \brief Combine the addressing modes we've collected into a single Index: test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll =================================================================== --- test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll +++ test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll @@ -17,3 +17,18 @@ ret i64 %v } +@gv1 = external global i8, align 16 +@gv2 = external global i8, align 16 + +; Select when both GV and base reg are present. +define i8 @test2(i1 %c, i64 %b) { +; CHECK-LABEL: @test2 +entry: +; CHECK-LABEL: entry: + %g1 = getelementptr inbounds i8, i8* @gv1, i64 %b + %g2 = getelementptr inbounds i8, i8* @gv2, i64 %b + %s = select i1 %c, i8* %g1, i8* %g2 +; CHECK-NOT: sunkaddr + %v = load i8 , i8* %s, align 8 + ret i8 %v +}