Avoid creating invalid sub/add instructions on the prolog/epilog
patch by Lauro llvm-svn: 32577
This commit is contained in:
		
							parent
							
								
									4c306ae0c2
								
							
						
					
					
						commit
						09e2921d9a
					
				| 
						 | 
					@ -35,6 +35,80 @@ static bool hasFP(const MachineFunction &MF) {
 | 
				
			||||||
  return NoFramePointerElim || MFI->hasVarSizedObjects();
 | 
					  return NoFramePointerElim || MFI->hasVarSizedObjects();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ROTATE32L(x, n) (((x) << (n)) | ((x)  >> (32 - (n))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ROTATE32R(x, n) (((x) >> (n)) | ((x)  << (32 - (n))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// finds the end position of largest sequence of zeros in binary representation
 | 
				
			||||||
 | 
					// of 'immediate'.
 | 
				
			||||||
 | 
					static int findLargestZeroSequence(unsigned immediate){
 | 
				
			||||||
 | 
					  int max_zero_pos;
 | 
				
			||||||
 | 
					  int max_zero_length = 0;
 | 
				
			||||||
 | 
					  int zero_pos;
 | 
				
			||||||
 | 
					  int zero_length;
 | 
				
			||||||
 | 
					  int pos = 0;
 | 
				
			||||||
 | 
					  int end_pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while ((immediate & 0x3) == 0) {
 | 
				
			||||||
 | 
					    immediate = ROTATE32R(immediate, 2);
 | 
				
			||||||
 | 
					    pos+=2;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  end_pos = pos+32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (pos<end_pos){
 | 
				
			||||||
 | 
					    while ((immediate & 0x3) != 0) {
 | 
				
			||||||
 | 
					      immediate = ROTATE32R(immediate, 2);
 | 
				
			||||||
 | 
					      pos+=2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    zero_pos = pos;
 | 
				
			||||||
 | 
					    while ((immediate & 0x3) == 0) {
 | 
				
			||||||
 | 
					      immediate = ROTATE32R(immediate, 2);
 | 
				
			||||||
 | 
					      pos+=2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    zero_length = pos - zero_pos;
 | 
				
			||||||
 | 
					    if (zero_length > max_zero_length){
 | 
				
			||||||
 | 
					      max_zero_length = zero_length;
 | 
				
			||||||
 | 
					      max_zero_pos = zero_pos % 32;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (max_zero_pos + max_zero_length) % 32;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void splitInstructionWithImmediate(MachineBasicBlock &BB,
 | 
				
			||||||
 | 
									       MachineBasicBlock::iterator I,
 | 
				
			||||||
 | 
									       const TargetInstrDescriptor &TID,
 | 
				
			||||||
 | 
									       unsigned DestReg,
 | 
				
			||||||
 | 
									       unsigned OrigReg,
 | 
				
			||||||
 | 
									       unsigned immediate){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (immediate == 0){
 | 
				
			||||||
 | 
					    BuildMI(BB, I, TID, DestReg).addReg(OrigReg).addImm(0)
 | 
				
			||||||
 | 
						.addImm(0).addImm(ARMShift::LSL);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int start_pos = findLargestZeroSequence(immediate);
 | 
				
			||||||
 | 
					  unsigned immediate_tmp = ROTATE32R(immediate, start_pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int pos = 0;
 | 
				
			||||||
 | 
					  while (pos < 32){
 | 
				
			||||||
 | 
					    while(((immediate_tmp&0x3) == 0)&&(pos<32)){
 | 
				
			||||||
 | 
					      immediate_tmp = ROTATE32R(immediate_tmp,2);
 | 
				
			||||||
 | 
					      pos+=2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (pos < 32){
 | 
				
			||||||
 | 
					      BuildMI(BB, I, TID, DestReg).addReg(OrigReg)
 | 
				
			||||||
 | 
						.addImm(ROTATE32L(immediate_tmp&0xFF, (start_pos + pos) % 32 ))
 | 
				
			||||||
 | 
						.addImm(0).addImm(ARMShift::LSL);
 | 
				
			||||||
 | 
					      immediate_tmp = ROTATE32R(immediate_tmp,8);
 | 
				
			||||||
 | 
					      pos+=8;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii)
 | 
					ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii)
 | 
				
			||||||
  : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
 | 
					  : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
 | 
				
			||||||
    TII(tii) {
 | 
					    TII(tii) {
 | 
				
			||||||
| 
						 | 
					@ -110,13 +184,13 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (Old->getOpcode() == ARM::ADJCALLSTACKDOWN) {
 | 
					      if (Old->getOpcode() == ARM::ADJCALLSTACKDOWN) {
 | 
				
			||||||
        // sub sp, sp, amount
 | 
					        // sub sp, sp, amount
 | 
				
			||||||
        BuildMI(MBB, I, TII.get(ARM::SUB), ARM::R13).addReg(ARM::R13).addImm(Amount)
 | 
						splitInstructionWithImmediate(MBB, I, TII.get(ARM::SUB), ARM::R13,
 | 
				
			||||||
          .addImm(0).addImm(ARMShift::LSL);
 | 
									   ARM::R13, Amount);
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        // add sp, sp, amount
 | 
					        // add sp, sp, amount
 | 
				
			||||||
        assert(Old->getOpcode() == ARM::ADJCALLSTACKUP);
 | 
					        assert(Old->getOpcode() == ARM::ADJCALLSTACKUP);
 | 
				
			||||||
        BuildMI(MBB, I, TII.get(ARM::ADD), ARM::R13).addReg(ARM::R13).addImm(Amount)
 | 
						splitInstructionWithImmediate(MBB, I, TII.get(ARM::ADD), ARM::R13,
 | 
				
			||||||
          .addImm(0).addImm(ARMShift::LSL);
 | 
									   ARM::R13, Amount);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -156,8 +230,8 @@ ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
 | 
				
			||||||
    // Insert a set of r12 with the full address
 | 
					    // Insert a set of r12 with the full address
 | 
				
			||||||
    // r12 = r13 + offset
 | 
					    // r12 = r13 + offset
 | 
				
			||||||
    MachineBasicBlock *MBB2 = MI.getParent();
 | 
					    MachineBasicBlock *MBB2 = MI.getParent();
 | 
				
			||||||
    BuildMI(*MBB2, II, TII.get(ARM::ADD), ARM::R12).addReg(BaseRegister)
 | 
					    splitInstructionWithImmediate(*MBB2, II, TII.get(ARM::ADD), ARM::R12,
 | 
				
			||||||
      .addImm(Offset).addImm(0).addImm(ARMShift::LSL);
 | 
								       BaseRegister, Offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Replace the FrameIndex with r12
 | 
					    // Replace the FrameIndex with r12
 | 
				
			||||||
    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
 | 
					    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
 | 
				
			||||||
| 
						 | 
					@ -192,8 +266,9 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
 | 
				
			||||||
  MFI->setStackSize(NumBytes);
 | 
					  MFI->setStackSize(NumBytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //sub sp, sp, #NumBytes
 | 
					  //sub sp, sp, #NumBytes
 | 
				
			||||||
  BuildMI(MBB, MBBI, TII.get(ARM::SUB), ARM::R13).addReg(ARM::R13).addImm(NumBytes)
 | 
					  splitInstructionWithImmediate(MBB, MBBI, TII.get(ARM::SUB), ARM::R13,
 | 
				
			||||||
	  .addImm(0).addImm(ARMShift::LSL);
 | 
								     ARM::R13, NumBytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (HasFP) {
 | 
					  if (HasFP) {
 | 
				
			||||||
    BuildMI(MBB, MBBI, TII.get(ARM::STR))
 | 
					    BuildMI(MBB, MBBI, TII.get(ARM::STR))
 | 
				
			||||||
| 
						 | 
					@ -219,8 +294,9 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //add sp, sp, #NumBytes
 | 
					  //add sp, sp, #NumBytes
 | 
				
			||||||
  BuildMI(MBB, MBBI, TII.get(ARM::ADD), ARM::R13).addReg(ARM::R13).addImm(NumBytes)
 | 
					  splitInstructionWithImmediate(MBB, MBBI, TII.get(ARM::ADD), ARM::R13,
 | 
				
			||||||
	  .addImm(0).addImm(ARMShift::LSL);
 | 
								     ARM::R13, NumBytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned ARMRegisterInfo::getRARegister() const {
 | 
					unsigned ARMRegisterInfo::getRARegister() const {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm &&
 | 
				
			||||||
 | 
					; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | not grep "805306384"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int %main() {
 | 
				
			||||||
 | 
					entry:
 | 
				
			||||||
 | 
						%retval = alloca int, align 4		; <int*> [#uses=2]
 | 
				
			||||||
 | 
						%tmp = alloca int, align 4		; <int*> [#uses=2]
 | 
				
			||||||
 | 
						%a = alloca [805306369 x sbyte], align 16		; <[805306369 x sbyte]*> [#uses=0]
 | 
				
			||||||
 | 
						"alloca point" = bitcast int 0 to int		; <int> [#uses=0]
 | 
				
			||||||
 | 
						store int 0, int* %tmp
 | 
				
			||||||
 | 
						%tmp = load int* %tmp		; <int> [#uses=1]
 | 
				
			||||||
 | 
						store int %tmp, int* %retval
 | 
				
			||||||
 | 
						br label %return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return:		; preds = %entry
 | 
				
			||||||
 | 
						%retval = load int* %retval		; <int> [#uses=1]
 | 
				
			||||||
 | 
						ret int %retval
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue