[llvm-commits] [llvm] r43032 - in /llvm/trunk: lib/Target/PowerPC/PPCRegisterInfo.cpp test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll

Chris Lattner sabre at nondot.org
Tue Oct 16 11:00:19 PDT 2007


Author: lattner
Date: Tue Oct 16 13:00:18 2007
New Revision: 43032

URL: http://llvm.org/viewvc/llvm-project?rev=43032&view=rev
Log:
Fix a bug handling frame references in ppc inline asm when the frame offset
doesn't fit into 16 bits.

Added:
    llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp

Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=43032&r1=43031&r2=43032&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Tue Oct 16 13:00:18 2007
@@ -722,18 +722,19 @@
   MachineFrameInfo *MFI = MF.getFrameInfo();
 
   // Find out which operand is the frame index.
-  unsigned i = 0;
-  while (!MI.getOperand(i).isFrameIndex()) {
-    ++i;
-    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
+  unsigned FIOperandNo = 0;
+  while (!MI.getOperand(FIOperandNo).isFrameIndex()) {
+    ++FIOperandNo;
+    assert(FIOperandNo != MI.getNumOperands() &&
+           "Instr doesn't have FrameIndex operand!");
   }
   // Take into account whether it's an add or mem instruction
-  unsigned OffIdx = (i == 2) ? 1 : 2;
+  unsigned OffsetOperandNo = (FIOperandNo == 2) ? 1 : 2;
   if (MI.getOpcode() == TargetInstrInfo::INLINEASM)
-    OffIdx = i-1;
+    OffsetOperandNo = FIOperandNo-1;
       
   // Get the frame index.
-  int FrameIndex = MI.getOperand(i).getFrameIndex();
+  int FrameIndex = MI.getOperand(FIOperandNo).getFrameIndex();
   
   // Get the frame pointer save index.  Users of this index are primarily
   // DYNALLOC instructions.
@@ -750,7 +751,8 @@
   }
 
   // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
-  MI.getOperand(i).ChangeToRegister(hasFP(MF) ? PPC::R31 : PPC::R1, false);
+  MI.getOperand(FIOperandNo).ChangeToRegister(hasFP(MF) ? PPC::R31 : PPC::R1,
+                                              false);
 
   // Figure out if the offset in the instruction is shifted right two bits. This
   // is true for instructions like "STD", which the machine implicitly adds two
@@ -767,37 +769,44 @@
   
   // Now add the frame object offset to the offset from r1.
   int Offset = MFI->getObjectOffset(FrameIndex);
-  
   if (!isIXAddr)
-    Offset += MI.getOperand(OffIdx).getImmedValue();
+    Offset += MI.getOperand(OffsetOperandNo).getImmedValue();
   else
-    Offset += MI.getOperand(OffIdx).getImmedValue() << 2;
+    Offset += MI.getOperand(OffsetOperandNo).getImmedValue() << 2;
 
   // If we're not using a Frame Pointer that has been set to the value of the
   // SP before having the stack size subtracted from it, then add the stack size
   // to Offset to get the correct offset.
   Offset += MFI->getStackSize();
 
-  if (!isInt16(Offset)) {
+  if (isInt16(Offset)) {
+    if (isIXAddr) {
+      assert((Offset & 3) == 0 && "Invalid frame offset!");
+      Offset >>= 2;    // The actual encoded value has the low two bits zero.
+    }
+    MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset);
+  } else {
     // Insert a set of r0 with the full offset value before the ld, st, or add
     BuildMI(MBB, II, TII.get(PPC::LIS), PPC::R0).addImm(Offset >> 16);
     BuildMI(MBB, II, TII.get(PPC::ORI), PPC::R0).addReg(PPC::R0).addImm(Offset);
     
-    // convert into indexed form of the instruction
+    // Convert into indexed form of the instruction
     // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
     // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
-    assert(ImmToIdxMap.count(OpC) &&
-           "No indexed form of load or store available!");
-    unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
-    MI.setInstrDescriptor(TII.get(NewOpcode));
-    MI.getOperand(1).ChangeToRegister(MI.getOperand(i).getReg(), false);
-    MI.getOperand(2).ChangeToRegister(PPC::R0, false);
-  } else {
-    if (isIXAddr) {
-      assert((Offset & 3) == 0 && "Invalid frame offset!");
-      Offset >>= 2;    // The actual encoded value has the low two bits zero.
+    unsigned OperandBase;
+    if (OpC != TargetInstrInfo::INLINEASM) {
+      assert(ImmToIdxMap.count(OpC) &&
+             "No indexed form of load or store available!");
+      unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
+      MI.setInstrDescriptor(TII.get(NewOpcode));
+      OperandBase = 1;
+    } else {
+      OperandBase = OffsetOperandNo;
     }
-    MI.getOperand(OffIdx).ChangeToImmediate(Offset);
+      
+    unsigned StackReg = MI.getOperand(FIOperandNo).getReg();
+    MI.getOperand(OperandBase).ChangeToRegister(StackReg, false);
+    MI.getOperand(OperandBase+1).ChangeToRegister(PPC::R0, false);
   }
 }
 

Added: llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll?rev=43032&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/2007-10-16-InlineAsmFrameOffset.ll Tue Oct 16 13:00:18 2007
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | llc -march=ppc32
+; rdar://5538377
+
+        %struct.disk_unsigned = type { i32 }
+        %struct._StorePageMax = type { %struct.disk_unsigned, %struct.disk_unsigned, [65536 x i8] }
+
+define i32 @test() {
+entry:
+        %data = alloca i32              ; <i32*> [#uses=1]
+        %compressedPage = alloca %struct._StorePageMax          ; <%struct._StorePageMax*> [#uses=0]
+        %tmp107 = call i32 asm "lwbrx $0, $2, $1", "=r,r,bO,*m"( i8* null, i32 0, i32* %data )          ; <i32> [#uses=0]
+        unreachable
+}
+





More information about the llvm-commits mailing list