[llvm-commits] [llvm] r44378 - in /llvm/trunk: lib/Target/PowerPC/PPCRegisterInfo.cpp test/CodeGen/Generic/invalid-memcpy.ll test/CodeGen/PowerPC/invalid-memcpy.ll

Chris Lattner sabre at nondot.org
Tue Nov 27 14:14:43 PST 2007


Author: lattner
Date: Tue Nov 27 16:14:42 2007
New Revision: 44378

URL: http://llvm.org/viewvc/llvm-project?rev=44378&view=rev
Log:
Fix a crash on invalid code due to memcpy lowering.

Added:
    llvm/trunk/test/CodeGen/Generic/invalid-memcpy.ll
    llvm/trunk/test/CodeGen/PowerPC/invalid-memcpy.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=44378&r1=44377&r2=44378&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Tue Nov 27 16:14:42 2007
@@ -779,35 +779,40 @@
   // to Offset to get the correct offset.
   Offset += MFI->getStackSize();
 
-  if (isInt16(Offset)) {
-    if (isIXAddr) {
-      assert((Offset & 3) == 0 && "Invalid frame offset!");
+  // If we can, encode the offset directly into the instruction.  If this is a
+  // normal PPC "ri" instruction, any 16-bit value can be safely encoded.  If
+  // this is a PPC64 "ix" instruction, only a 16-bit value with the low two bits
+  // clear can be encoded.  This is extremely uncommon, because normally you
+  // only "std" to a stack slot that is at least 4-byte aligned, but it can
+  // happen in invalid code.
+  if (isInt16(Offset) && (!isIXAddr || (isIXAddr & 3) == 0)) {
+    if (isIXAddr)
       Offset >>= 2;    // The actual encoded value has the low two bits zero.
-    }
     MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset);
+    return;
+  }
+  
+  // 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
+  // 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
+  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 {
-    // 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
-    // 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
-    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;
-    }
-      
-    unsigned StackReg = MI.getOperand(FIOperandNo).getReg();
-    MI.getOperand(OperandBase).ChangeToRegister(StackReg, false);
-    MI.getOperand(OperandBase+1).ChangeToRegister(PPC::R0, false);
+    OperandBase = OffsetOperandNo;
   }
+    
+  unsigned StackReg = MI.getOperand(FIOperandNo).getReg();
+  MI.getOperand(OperandBase).ChangeToRegister(StackReg, false);
+  MI.getOperand(OperandBase+1).ChangeToRegister(PPC::R0, false);
 }
 
 /// VRRegNo - Map from a numbered VR register to its enum value.

Added: llvm/trunk/test/CodeGen/Generic/invalid-memcpy.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/invalid-memcpy.ll?rev=44378&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/Generic/invalid-memcpy.ll (added)
+++ llvm/trunk/test/CodeGen/Generic/invalid-memcpy.ll Tue Nov 27 16:14:42 2007
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | llc 
+
+; This testcase is invalid (the alignment specified for memcpy is 
+; greater than the alignment guaranteed for Qux or C.0.1173), but it
+; should compile, not crash the code generator.
+
+ at C.0.1173 = external constant [33 x i8]         ; <[33 x i8]*> [#uses=1]
+
+define void @Bork() {
+entry:
+        %Qux = alloca [33 x i8]         ; <[33 x i8]*> [#uses=1]
+        %Qux1 = bitcast [33 x i8]* %Qux to i8*          ; <i8*> [#uses=1]
+        call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr ([33 x i8]* @C.0.1173, i32 0, i32 0), i64 33, i32 8 )
+        ret void
+}
+
+declare void @llvm.memcpy.i64(i8*, i8*, i64, i32)
+
+

Added: llvm/trunk/test/CodeGen/PowerPC/invalid-memcpy.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/invalid-memcpy.ll?rev=44378&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/invalid-memcpy.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/invalid-memcpy.ll Tue Nov 27 16:14:42 2007
@@ -0,0 +1,20 @@
+; RUN: llvm-as < %s | llc -march=ppc32
+; RUN: llvm-as < %s | llc -march=ppc64
+
+; This testcase is invalid (the alignment specified for memcpy is 
+; greater than the alignment guaranteed for Qux or C.0.1173, but it
+; should compile, not crash the code generator.
+
+ at C.0.1173 = external constant [33 x i8]         ; <[33 x i8]*> [#uses=1]
+
+define void @Bork() {
+entry:
+        %Qux = alloca [33 x i8]         ; <[33 x i8]*> [#uses=1]
+        %Qux1 = bitcast [33 x i8]* %Qux to i8*          ; <i8*> [#uses=1]
+        call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr ([33 x i8]* @C.0.1173, i32 0, i32 0), i64 33, i32 8 )
+        ret void
+}
+
+declare void @llvm.memcpy.i64(i8*, i8*, i64, i32)
+
+





More information about the llvm-commits mailing list