[PowerPC] Don't apply the PPC64 address-formation peephole for offsets greater than 7

When applying our address-formation PPC64 peephole, we are reusing the @ha TOC
addis value with the low parts associated with different offsets (i.e.
different effective symbol addends). We were assuming this was okay so long as
the offsets were less than the alignment of the global variable being accessed.
This ignored the fact, however, that the TOC base pointer itself need only be
8-byte aligned. As a result, what we were doing is legal only for offsets less
than 8 regardless of the alignment of the object being accessed.

Fixes PR28727.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280441 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hal Finkel 2016-09-02 00:28:20 +00:00
parent c426463f0b
commit 67a060f802
2 changed files with 12 additions and 5 deletions

View File

@ -4370,10 +4370,15 @@ void PPCDAGToDAGISel::PeepholePPC64() {
}
SDValue ImmOpnd = Base.getOperand(1);
int MaxDisplacement = 0;
// On PPC64, the TOC base pointer is guaranteed by the ABI only to have
// 8-byte alignment, and so we can only use offsets less than 8 (otherwise,
// we might have needed different @ha relocation values for the offset
// pointers).
int MaxDisplacement = 7;
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
const GlobalValue *GV = GA->getGlobal();
MaxDisplacement = GV->getAlignment() - 1;
MaxDisplacement = std::min((int) GV->getAlignment() - 1, MaxDisplacement);
}
int Offset = N->getConstantOperandVal(FirstOp);

View File

@ -208,12 +208,13 @@ entry:
; CHECK-LABEL: test_d2:
; CHECK: addis [[REGSTRUCT:[0-9]+]], 2, d2v@toc@ha
; CHECK: addi [[BASEV:[0-9]+]], [[REGSTRUCT]], d2v@toc@l
; CHECK-DAG: ld [[REG0_0:[0-9]+]], d2v@toc@l([[REGSTRUCT]])
; CHECK-DAG: ld [[REG1_0:[0-9]+]], d2v@toc@l+8([[REGSTRUCT]])
; CHECK-DAG: ld [[REG1_0:[0-9]+]], 8([[BASEV]])
; CHECK-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
; CHECK-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
; CHECK-DAG: std [[REG0_1]], d2v@toc@l([[REGSTRUCT]])
; CHECK-DAG: std [[REG1_1]], d2v@toc@l+8([[REGSTRUCT]])
; CHECK-DAG: std [[REG1_1]], 8([[BASEV]])
define void @test_d2() nounwind {
entry:
@ -229,7 +230,8 @@ entry:
; register 3 is the return value, so it should be chosen
; CHECK-LABEL: test_singleuse:
; CHECK: addis 3, 2, d2v@toc@ha
; CHECK: ld 3, d2v@toc@l+8(3)
; CHECK: addi 3, 3, d2v@toc@l
; CHECK: ld 3, 8(3)
define i64 @test_singleuse() nounwind {
entry:
%0 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8