@@ -7635,6 +7635,7 @@ void PPCDAGToDAGISel::PeepholePPC64() {
7635
7635
break ;
7636
7636
case PPC::ADDItoc:
7637
7637
case PPC::ADDItoc8:
7638
+ ReplaceFlags = false ;
7638
7639
if (RequiresMod4Offset) {
7639
7640
if (GlobalAddressSDNode *GA =
7640
7641
dyn_cast<GlobalAddressSDNode>(Base.getOperand (0 ))) {
@@ -7649,42 +7650,58 @@ void PPCDAGToDAGISel::PeepholePPC64() {
7649
7650
break ;
7650
7651
}
7651
7652
7652
- SDValue ImmOpnd = Base.getOperand (1 );
7653
+ const unsigned BaseOpcode = Base.getMachineOpcode ();
7654
+ // ADDItoc and ADDItoc8 are pseudos used exclusively by AIX small code
7655
+ // model when a global is defined in the TOC.
7656
+ const bool OpcodeIsAIXSmallTocData =
7657
+ BaseOpcode == PPC::ADDItoc || BaseOpcode == PPC::ADDItoc8;
7653
7658
7654
- // On PPC64, the TOC base pointer is guaranteed by the ABI only to have
7655
- // 8-byte alignment, and so we can only use offsets less than 8 (otherwise,
7656
- // we might have needed different @ha relocation values for the offset
7657
- // pointers).
7658
- int MaxDisplacement = 7 ;
7659
- if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
7660
- const GlobalValue *GV = GA-> getGlobal ();
7661
- Align Alignment = GV-> getPointerAlignment (CurDAG-> getDataLayout () );
7662
- MaxDisplacement = std::min (( int )Alignment. value () - 1 , MaxDisplacement );
7659
+ SDValue RegOperand;
7660
+ SDValue ImmOpnd;
7661
+ // The AIX small code model nodes have the operands reversed.
7662
+ if (OpcodeIsAIXSmallTocData) {
7663
+ RegOperand = Base. getOperand ( 1 ) ;
7664
+ ImmOpnd = Base. getOperand ( 0 );
7665
+ } else {
7666
+ RegOperand = Base. getOperand ( 0 );
7667
+ ImmOpnd = Base. getOperand ( 1 );
7663
7668
}
7664
7669
7665
- bool UpdateHBase = false ;
7666
- SDValue HBase = Base.getOperand (0 );
7667
-
7668
7670
int Offset = N->getConstantOperandVal (FirstOp);
7671
+
7672
+ SDValue HBase;
7673
+ bool UpdateHBase = false ;
7669
7674
if (ReplaceFlags) {
7675
+ // On PPC64, the TOC base pointer is guaranteed by the ABI only to have
7676
+ // 8-byte alignment, and so we can only use offsets less than 8
7677
+ // (otherwise, we might have needed different @ha relocation values for
7678
+ // the offset pointers).
7679
+ int MaxDisplacement = 7 ;
7680
+ if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
7681
+ const GlobalValue *GV = GA->getGlobal ();
7682
+ Align Alignment = GV->getPointerAlignment (CurDAG->getDataLayout ());
7683
+ MaxDisplacement = std::min ((int )Alignment.value () - 1 , MaxDisplacement);
7684
+ }
7685
+
7670
7686
if (Offset < 0 || Offset > MaxDisplacement) {
7671
7687
// If we have a addi(toc@l)/addis(toc@ha) pair, and the addis has only
7672
7688
// one use, then we can do this for any offset, we just need to also
7673
7689
// update the offset (i.e. the symbol addend) on the addis also.
7674
- if (Base. getMachineOpcode () != PPC::ADDItocL)
7690
+ if (BaseOpcode != PPC::ADDItocL)
7675
7691
continue ;
7676
7692
7677
- if (!HBase .isMachineOpcode () ||
7678
- HBase .getMachineOpcode () != PPC::ADDIStocHA8)
7693
+ if (!RegOperand .isMachineOpcode () ||
7694
+ RegOperand .getMachineOpcode () != PPC::ADDIStocHA8)
7679
7695
continue ;
7680
7696
7681
- if (!Base.hasOneUse () || !HBase .hasOneUse ())
7697
+ if (!Base.hasOneUse () || !RegOperand .hasOneUse ())
7682
7698
continue ;
7683
7699
7684
- SDValue HImmOpnd = HBase .getOperand (1 );
7700
+ SDValue HImmOpnd = RegOperand .getOperand (1 );
7685
7701
if (HImmOpnd != ImmOpnd)
7686
7702
continue ;
7687
7703
7704
+ HBase = RegOperand;
7688
7705
UpdateHBase = true ;
7689
7706
}
7690
7707
} else {
@@ -7709,10 +7726,10 @@ void PPCDAGToDAGISel::PeepholePPC64() {
7709
7726
}
7710
7727
}
7711
7728
7712
- // We found an opportunity. Reverse the operands from the add
7713
- // immediate and substitute them into the load or store. If
7714
- // needed, update the target flags for the immediate operand to
7715
- // reflect the necessary relocation information.
7729
+ // We found an opportunity. Forward the operands from the add
7730
+ // immediate to the load or store. If needed, update the target
7731
+ // flags for the immediate operand to reflect the necessary
7732
+ // relocation information.
7716
7733
LLVM_DEBUG (dbgs () << " Folding add-immediate into mem-op:\n Base: " );
7717
7734
LLVM_DEBUG (Base->dump (CurDAG));
7718
7735
LLVM_DEBUG (dbgs () << " \n N: " );
@@ -7728,6 +7745,10 @@ void PPCDAGToDAGISel::PeepholePPC64() {
7728
7745
Align Alignment = GV->getPointerAlignment (CurDAG->getDataLayout ());
7729
7746
// We can't perform this optimization for data whose alignment
7730
7747
// is insufficient for the instruction encoding.
7748
+ // TODO FIXME Verify and document why the offset must be a multiple of
7749
+ // 4 when the aligment is less than 4. It is not about the encoding of
7750
+ // the instruction: the value of Offset comes directly from the original
7751
+ // load/store instruction on the path that reaches this check.
7731
7752
if (Alignment < 4 && (RequiresMod4Offset || (Offset % 4 ) != 0 )) {
7732
7753
LLVM_DEBUG (dbgs () << " Rejected this candidate for alignment.\n\n " );
7733
7754
continue ;
@@ -7741,27 +7762,12 @@ void PPCDAGToDAGISel::PeepholePPC64() {
7741
7762
}
7742
7763
}
7743
7764
7744
- const unsigned BaseOpcode = Base.getMachineOpcode ();
7745
- // ADDItoc and ADDItoc8 are pseudos used exclusively by AIX small code
7746
- // model when a global is defined in the TOC.
7747
- const bool OpcodeIsAIXTocData =
7748
- BaseOpcode == PPC::ADDItoc || BaseOpcode == PPC::ADDItoc8;
7749
-
7750
7765
if (FirstOp == 1 ) // Store
7751
- if (OpcodeIsAIXTocData)
7752
- (void )CurDAG->UpdateNodeOperands (N, N->getOperand (0 ),
7753
- Base.getOperand (0 ), Base.getOperand (1 ),
7754
- N->getOperand (3 ));
7755
- else
7756
- (void )CurDAG->UpdateNodeOperands (N, N->getOperand (0 ), ImmOpnd,
7757
- Base.getOperand (0 ), N->getOperand (3 ));
7766
+ (void )CurDAG->UpdateNodeOperands (N, N->getOperand (0 ), ImmOpnd, RegOperand,
7767
+ N->getOperand (3 ));
7758
7768
else // Load
7759
- if (OpcodeIsAIXTocData)
7760
- (void )CurDAG->UpdateNodeOperands (N, Base.getOperand (0 ),
7761
- Base.getOperand (1 ), N->getOperand (2 ));
7762
- else
7763
- (void )CurDAG->UpdateNodeOperands (N, ImmOpnd, Base.getOperand (0 ),
7764
- N->getOperand (2 ));
7769
+ (void )CurDAG->UpdateNodeOperands (N, ImmOpnd, RegOperand,
7770
+ N->getOperand (2 ));
7765
7771
7766
7772
if (UpdateHBase)
7767
7773
(void )CurDAG->UpdateNodeOperands (HBase.getNode (), HBase.getOperand (0 ),
0 commit comments