Skip to content
  • Bill Schmidt's avatar
    Index: test/CodeGen/PowerPC/reloc-align.ll · 48fc20a0
    Bill Schmidt authored
    ===================================================================
    --- test/CodeGen/PowerPC/reloc-align.ll	(revision 0)
    +++ test/CodeGen/PowerPC/reloc-align.ll	(revision 0)
    @@ -0,0 +1,34 @@
    +; RUN: llc -mcpu=pwr7 -O1 < %s | FileCheck %s
    +
    +; This test verifies that the peephole optimization of address accesses
    +; does not produce a load or store with a relocation that can't be
    +; satisfied for a given instruction encoding.  Reduced from a test supplied
    +; by Hal Finkel.
    +
    +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
    +target triple = "powerpc64-unknown-linux-gnu"
    +
    +%struct.S1 = type { [8 x i8] }
    +
    +@main.l_1554 = internal global { i8, i8, i8, i8, i8, i8, i8, i8 } { i8 -1, i8 -6, i8 57, i8 62, i8 -48, i8 0, i8 58, i8 80 }, align 1
    +
    +; Function Attrs: nounwind readonly
    +define signext i32 @main() #0 {
    +entry:
    +  %call = tail call fastcc signext i32 @func_90(%struct.S1* byval bitcast ({ i8, i8, i8, i8, i8, i8, i8, i8 }* @main.l_1554 to %struct.S1*))
    +; CHECK-NOT: ld {{[0-9]+}}, main.l_1554@toc@l
    +  ret i32 %call
    +}
    +
    +; Function Attrs: nounwind readonly
    +define internal fastcc signext i32 @func_90(%struct.S1* byval nocapture %p_91) #0 {
    +entry:
    +  %0 = bitcast %struct.S1* %p_91 to i64*
    +  %bf.load = load i64* %0, align 1
    +  %bf.shl = shl i64 %bf.load, 26
    +  %bf.ashr = ashr i64 %bf.shl, 54
    +  %bf.cast = trunc i64 %bf.ashr to i32
    +  ret i32 %bf.cast
    +}
    +
    +attributes #0 = { nounwind readonly "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
    Index: lib/Target/PowerPC/PPCAsmPrinter.cpp
    ===================================================================
    --- lib/Target/PowerPC/PPCAsmPrinter.cpp	(revision 185327)
    +++ lib/Target/PowerPC/PPCAsmPrinter.cpp	(working copy)
    @@ -679,7 +679,26 @@ void PPCAsmPrinter::EmitInstruction(const MachineI
           OutStreamer.EmitRawText(StringRef("\tmsync"));
           return;
         }
    +    break;
    +  case PPC::LD:
    +  case PPC::STD:
    +  case PPC::LWA: {
    +    // Verify alignment is legal, so we don't create relocations
    +    // that can't be supported.
    +    // FIXME:  This test is currently disabled for Darwin.  The test
    +    // suite shows a handful of test cases that fail this check for
    +    // Darwin.  Those need to be investigated before this sanity test
    +    // can be enabled for those subtargets.
    +    if (!Subtarget.isDarwin()) {
    +      unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
    +      const MachineOperand &MO = MI->getOperand(OpNum);
    +      if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
    +        llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
    +    }
    +    // Now process the instruction normally.
    +    break;
       }
    +  }
     
       LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
       OutStreamer.EmitInstruction(TmpInst);
    Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp
    ===================================================================
    --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp	(revision 185327)
    +++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp	(working copy)
    @@ -1530,6 +1530,14 @@ void PPCDAGToDAGISel::PostprocessISelDAG() {
           if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
             SDLoc dl(GA);
             const GlobalValue *GV = GA->getGlobal();
    +        // We can't perform this optimization for data whose alignment
    +        // is insufficient for the instruction encoding.
    +        if (GV->getAlignment() < 4 &&
    +            (StorageOpcode == PPC::LD || StorageOpcode == PPC::STD ||
    +             StorageOpcode == PPC::LWA)) {
    +          DEBUG(dbgs() << "Rejected this candidate for alignment.\n\n");
    +          continue;
    +        }
             ImmOpnd = CurDAG->getTargetGlobalAddress(GV, dl, MVT::i64, 0, Flags);
           } else if (ConstantPoolSDNode *CP =
                      dyn_cast<ConstantPoolSDNode>(ImmOpnd)) {
    
    llvm-svn: 185380
    48fc20a0
Loading