From 17e5794f11c72ed95a6208191ccc3efedbdd4794 Mon Sep 17 00:00:00 2001 From: Serguei Katkov Date: Tue, 23 Jan 2018 12:07:49 +0000 Subject: [CGP] Fix the GV handling in complex addressing mode If in complex addressing mode the difference is in GV then base reg should not be installed because we plan to use base reg as a merge point of different GVs. This is a fix for PR35980. Reviewers: reames, john.brawn, santosh Reviewed By: john.brawn Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D42230 llvm-svn: 323192 --- llvm/lib/CodeGen/CodeGenPrepare.cpp | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp') diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index eb2e3320a95..f11bc5afb25 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -2694,26 +2694,32 @@ public: 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 -- cgit v1.2.3