llvm.org GIT mirror llvm / 789db09
Fix a crash on invalid code due to memcpy lowering. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44378 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 12 years ago
3 changed file(s) with 70 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
778778 // to Offset to get the correct offset.
779779 Offset += MFI->getStackSize();
780780
781 if (isInt16(Offset)) {
782 if (isIXAddr) {
783 assert((Offset & 3) == 0 && "Invalid frame offset!");
781 // If we can, encode the offset directly into the instruction. If this is a
782 // normal PPC "ri" instruction, any 16-bit value can be safely encoded. If
783 // this is a PPC64 "ix" instruction, only a 16-bit value with the low two bits
784 // clear can be encoded. This is extremely uncommon, because normally you
785 // only "std" to a stack slot that is at least 4-byte aligned, but it can
786 // happen in invalid code.
787 if (isInt16(Offset) && (!isIXAddr || (isIXAddr & 3) == 0)) {
788 if (isIXAddr)
784789 Offset >>= 2; // The actual encoded value has the low two bits zero.
785 }
786790 MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset);
791 return;
792 }
793
794 // Insert a set of r0 with the full offset value before the ld, st, or add
795 BuildMI(MBB, II, TII.get(PPC::LIS), PPC::R0).addImm(Offset >> 16);
796 BuildMI(MBB, II, TII.get(PPC::ORI), PPC::R0).addReg(PPC::R0).addImm(Offset);
797
798 // Convert into indexed form of the instruction
799 // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
800 // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
801 unsigned OperandBase;
802 if (OpC != TargetInstrInfo::INLINEASM) {
803 assert(ImmToIdxMap.count(OpC) &&
804 "No indexed form of load or store available!");
805 unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
806 MI.setInstrDescriptor(TII.get(NewOpcode));
807 OperandBase = 1;
787808 } else {
788 // Insert a set of r0 with the full offset value before the ld, st, or add
789 BuildMI(MBB, II, TII.get(PPC::LIS), PPC::R0).addImm(Offset >> 16);
790 BuildMI(MBB, II, TII.get(PPC::ORI), PPC::R0).addReg(PPC::R0).addImm(Offset);
791
792 // Convert into indexed form of the instruction
793 // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
794 // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
795 unsigned OperandBase;
796 if (OpC != TargetInstrInfo::INLINEASM) {
797 assert(ImmToIdxMap.count(OpC) &&
798 "No indexed form of load or store available!");
799 unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
800 MI.setInstrDescriptor(TII.get(NewOpcode));
801 OperandBase = 1;
802 } else {
803 OperandBase = OffsetOperandNo;
804 }
805
806 unsigned StackReg = MI.getOperand(FIOperandNo).getReg();
807 MI.getOperand(OperandBase).ChangeToRegister(StackReg, false);
808 MI.getOperand(OperandBase+1).ChangeToRegister(PPC::R0, false);
809 }
809 OperandBase = OffsetOperandNo;
810 }
811
812 unsigned StackReg = MI.getOperand(FIOperandNo).getReg();
813 MI.getOperand(OperandBase).ChangeToRegister(StackReg, false);
814 MI.getOperand(OperandBase+1).ChangeToRegister(PPC::R0, false);
810815 }
811816
812817 /// VRRegNo - Map from a numbered VR register to its enum value.
0 ; RUN: llvm-as < %s | llc
1
2 ; This testcase is invalid (the alignment specified for memcpy is
3 ; greater than the alignment guaranteed for Qux or C.0.1173), but it
4 ; should compile, not crash the code generator.
5
6 @C.0.1173 = external constant [33 x i8] ; <[33 x i8]*> [#uses=1]
7
8 define void @Bork() {
9 entry:
10 %Qux = alloca [33 x i8] ; <[33 x i8]*> [#uses=1]
11 %Qux1 = bitcast [33 x i8]* %Qux to i8* ; [#uses=1]
12 call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr ([33 x i8]* @C.0.1173, i32 0, i32 0), i64 33, i32 8 )
13 ret void
14 }
15
16 declare void @llvm.memcpy.i64(i8*, i8*, i64, i32)
17
18
0 ; RUN: llvm-as < %s | llc -march=ppc32
1 ; RUN: llvm-as < %s | llc -march=ppc64
2
3 ; This testcase is invalid (the alignment specified for memcpy is
4 ; greater than the alignment guaranteed for Qux or C.0.1173, but it
5 ; should compile, not crash the code generator.
6
7 @C.0.1173 = external constant [33 x i8] ; <[33 x i8]*> [#uses=1]
8
9 define void @Bork() {
10 entry:
11 %Qux = alloca [33 x i8] ; <[33 x i8]*> [#uses=1]
12 %Qux1 = bitcast [33 x i8]* %Qux to i8* ; [#uses=1]
13 call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr ([33 x i8]* @C.0.1173, i32 0, i32 0), i64 33, i32 8 )
14 ret void
15 }
16
17 declare void @llvm.memcpy.i64(i8*, i8*, i64, i32)
18
19