forked from OSchip/llvm-project
[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:
parent
c159aa6aeb
commit
17e5794f11
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue