summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp9
-rw-r--r--llvm/test/CodeGen/PowerPC/peephole-align.ll8
2 files changed, 12 insertions, 5 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index f30aecf3000..23ee3e7312f 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -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);
diff --git a/llvm/test/CodeGen/PowerPC/peephole-align.ll b/llvm/test/CodeGen/PowerPC/peephole-align.ll
index cb0dde91242..1be84170734 100644
--- a/llvm/test/CodeGen/PowerPC/peephole-align.ll
+++ b/llvm/test/CodeGen/PowerPC/peephole-align.ll
@@ -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
OpenPOWER on IntegriCloud