aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Fertile <sd.fertile@gmail.com>2023-08-15 10:03:08 -0400
committerTobias Hieta <tobias@hieta.se>2023-08-22 09:02:57 +0200
commit28874feff022b096fcbb403699666517cf7de713 (patch)
tree0fc0af68cd169a76149c57ee8a384fdc83937ed9
parent60a88d4bab72b7c7c5634d58e0b6c08c398991de (diff)
downloadllvm-28874feff022b096fcbb403699666517cf7de713.zip
llvm-28874feff022b096fcbb403699666517cf7de713.tar.gz
llvm-28874feff022b096fcbb403699666517cf7de713.tar.bz2
Revert "[PPC][AIX] Fix toc-data peephole bug and some related cleanup."
This reverts commit b37c7ed0c95c7f24758b1532f04275b4bb65d3c1. (cherry picked from commit ce658829c9ebd23066f4f0aa5dc686350e5f9ba4)
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp88
-rw-r--r--llvm/test/CodeGen/PowerPC/aix-toc-data-offset.ll20
2 files changed, 41 insertions, 67 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 9f52da5..0ebfc00 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -7635,7 +7635,6 @@ void PPCDAGToDAGISel::PeepholePPC64() {
break;
case PPC::ADDItoc:
case PPC::ADDItoc8:
- ReplaceFlags = false;
if (RequiresMod4Offset) {
if (GlobalAddressSDNode *GA =
dyn_cast<GlobalAddressSDNode>(Base.getOperand(0))) {
@@ -7650,58 +7649,42 @@ void PPCDAGToDAGISel::PeepholePPC64() {
break;
}
- const unsigned BaseOpcode = Base.getMachineOpcode();
- // ADDItoc and ADDItoc8 are pseudos used exclusively by AIX small code
- // model when a global is defined in the TOC.
- const bool OpcodeIsAIXSmallTocData =
- BaseOpcode == PPC::ADDItoc || BaseOpcode == PPC::ADDItoc8;
+ SDValue ImmOpnd = Base.getOperand(1);
- SDValue RegOperand;
- SDValue ImmOpnd;
- // The AIX small code model nodes have the operands reversed.
- if (OpcodeIsAIXSmallTocData) {
- RegOperand = Base.getOperand(1);
- ImmOpnd = Base.getOperand(0);
- } else {
- RegOperand = Base.getOperand(0);
- ImmOpnd = Base.getOperand(1);
+ // 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();
+ Align Alignment = GV->getPointerAlignment(CurDAG->getDataLayout());
+ MaxDisplacement = std::min((int)Alignment.value() - 1, MaxDisplacement);
}
- int Offset = N->getConstantOperandVal(FirstOp);
-
- SDValue HBase;
bool UpdateHBase = false;
- if (ReplaceFlags) {
- // 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();
- Align Alignment = GV->getPointerAlignment(CurDAG->getDataLayout());
- MaxDisplacement = std::min((int)Alignment.value() - 1, MaxDisplacement);
- }
+ SDValue HBase = Base.getOperand(0);
+ int Offset = N->getConstantOperandVal(FirstOp);
+ if (ReplaceFlags) {
if (Offset < 0 || Offset > MaxDisplacement) {
// If we have a addi(toc@l)/addis(toc@ha) pair, and the addis has only
// one use, then we can do this for any offset, we just need to also
// update the offset (i.e. the symbol addend) on the addis also.
- if (BaseOpcode != PPC::ADDItocL)
+ if (Base.getMachineOpcode() != PPC::ADDItocL)
continue;
- if (!RegOperand.isMachineOpcode() ||
- RegOperand.getMachineOpcode() != PPC::ADDIStocHA8)
+ if (!HBase.isMachineOpcode() ||
+ HBase.getMachineOpcode() != PPC::ADDIStocHA8)
continue;
- if (!Base.hasOneUse() || !RegOperand.hasOneUse())
+ if (!Base.hasOneUse() || !HBase.hasOneUse())
continue;
- SDValue HImmOpnd = RegOperand.getOperand(1);
+ SDValue HImmOpnd = HBase.getOperand(1);
if (HImmOpnd != ImmOpnd)
continue;
- HBase = RegOperand;
UpdateHBase = true;
}
} else {
@@ -7726,10 +7709,10 @@ void PPCDAGToDAGISel::PeepholePPC64() {
}
}
- // We found an opportunity. Forward the operands from the add
- // immediate to the load or store. If needed, update the target
- // flags for the immediate operand to reflect the necessary
- // relocation information.
+ // We found an opportunity. Reverse the operands from the add
+ // immediate and substitute them into the load or store. If
+ // needed, update the target flags for the immediate operand to
+ // reflect the necessary relocation information.
LLVM_DEBUG(dbgs() << "Folding add-immediate into mem-op:\nBase: ");
LLVM_DEBUG(Base->dump(CurDAG));
LLVM_DEBUG(dbgs() << "\nN: ");
@@ -7745,10 +7728,6 @@ void PPCDAGToDAGISel::PeepholePPC64() {
Align Alignment = GV->getPointerAlignment(CurDAG->getDataLayout());
// We can't perform this optimization for data whose alignment
// is insufficient for the instruction encoding.
- // TODO FIXME Verify and document why the offset must be a multiple of
- // 4 when the aligment is less than 4. It is not about the encoding of
- // the instruction: the value of Offset comes directly from the original
- // load/store instruction on the path that reaches this check.
if (Alignment < 4 && (RequiresMod4Offset || (Offset % 4) != 0)) {
LLVM_DEBUG(dbgs() << "Rejected this candidate for alignment.\n\n");
continue;
@@ -7762,12 +7741,27 @@ void PPCDAGToDAGISel::PeepholePPC64() {
}
}
+ const unsigned BaseOpcode = Base.getMachineOpcode();
+ // ADDItoc and ADDItoc8 are pseudos used exclusively by AIX small code
+ // model when a global is defined in the TOC.
+ const bool OpcodeIsAIXTocData =
+ BaseOpcode == PPC::ADDItoc || BaseOpcode == PPC::ADDItoc8;
+
if (FirstOp == 1) // Store
- (void)CurDAG->UpdateNodeOperands(N, N->getOperand(0), ImmOpnd, RegOperand,
- N->getOperand(3));
+ if (OpcodeIsAIXTocData)
+ (void)CurDAG->UpdateNodeOperands(N, N->getOperand(0),
+ Base.getOperand(0), Base.getOperand(1),
+ N->getOperand(3));
+ else
+ (void)CurDAG->UpdateNodeOperands(N, N->getOperand(0), ImmOpnd,
+ Base.getOperand(0), N->getOperand(3));
else // Load
- (void)CurDAG->UpdateNodeOperands(N, ImmOpnd, RegOperand,
- N->getOperand(2));
+ if (OpcodeIsAIXTocData)
+ (void)CurDAG->UpdateNodeOperands(N, Base.getOperand(0),
+ Base.getOperand(1), N->getOperand(2));
+ else
+ (void)CurDAG->UpdateNodeOperands(N, ImmOpnd, Base.getOperand(0),
+ N->getOperand(2));
if (UpdateHBase)
(void)CurDAG->UpdateNodeOperands(HBase.getNode(), HBase.getOperand(0),
diff --git a/llvm/test/CodeGen/PowerPC/aix-toc-data-offset.ll b/llvm/test/CodeGen/PowerPC/aix-toc-data-offset.ll
deleted file mode 100644
index b3ece6b..0000000
--- a/llvm/test/CodeGen/PowerPC/aix-toc-data-offset.ll
+++ /dev/null
@@ -1,20 +0,0 @@
-; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
-; RUN: FileCheck %s
-
-; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
-; RUN: FileCheck %s
-
-@x = local_unnamed_addr global i32 218114560, align 4 #0
-
-define i32 @main() local_unnamed_addr {
-entry:
- %0 = load i32, ptr @x, align 4
- %shr = lshr i32 %0, 8
- %and = and i32 %shr, 255
- ret i32 %and
-}
-
-attributes #0 = { "toc-data" }
-
-; CHECK: la [[ADDR:[0-9]+]], x[TD](2)
-; CHECK: lbz {{.*}}, 2([[ADDR]])