[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
This commit is contained in:
Serguei Katkov 2018-01-23 12:07:49 +00:00
parent c159aa6aeb
commit 17e5794f11
2 changed files with 37 additions and 16 deletions

View File

@ -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)) {
AddrModes.emplace_back(NewAddrMode);
return true;
}
CanHandle = CanHandle && (DifferentField != ExtAddrMode::BaseOffsField ||
!NewAddrMode.ScaledReg);
// We couldn't combine NewAddrMode with the rest, so return failure.
AddrModes.clear();
return false;
// 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);
else
AddrModes.clear();
return CanHandle;
}
/// \brief Combine the addressing modes we've collected into a single

View File

@ -17,3 +17,18 @@ entry:
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
}