diff options
author | Xerxes Rånby <xerxes@zafena.se> | 2010-07-20 17:11:02 +0200 |
---|---|---|
committer | Xerxes Rånby <xerxes@zafena.se> | 2010-07-20 17:33:44 +0200 |
commit | d1dcd08e4ec0b65aaaef149bace47da16acf7626 (patch) | |
tree | b81ff7ee593fdf4de867c604ddd71e44da16df93 /recipes/llvm/llvm2.7 | |
parent | 84badc89f2ce0fc1f6f30e5197da9b053692b79f (diff) |
llvm2.7: new ARMv4 rawMOVLRPC.patch; backported llvm2.8svn r97745 & r104587 fixes.
* llvm2.7/MOVLRPC.patch: deleted.
* llvm2.7/rawMOVLRPC.patch: New patch replaces MOVLRPC.patch.
emits mov lr, pc before indirect call_nolink branches
using pseudo instructions for improved stablility on ARMv4 and ARMv4t.
fixes segfault after called function return. llvm PR7608
* llvm2.7/r97745-llvmPR6480.patch: New backported from llvm2.8svn.
fixes Assertion `SubUsed && "Using an undefined register!"' failed.
* llvm2.7/r104587-MOVimm32.patch: New backported from llvm2.8svn.
fixes TestARMCodeEmitter::emitPseudoInstruction UNREACHABLE
at ARMCodeEmitter.cpp:554
Diffstat (limited to 'recipes/llvm/llvm2.7')
-rw-r--r-- | recipes/llvm/llvm2.7/MOVLRPC.patch | 106 | ||||
-rw-r--r-- | recipes/llvm/llvm2.7/r104587-MOVimm32.patch | 190 | ||||
-rw-r--r-- | recipes/llvm/llvm2.7/r97745-llvmPR6480.patch | 75 | ||||
-rw-r--r-- | recipes/llvm/llvm2.7/rawMOVLRPC.patch | 61 |
4 files changed, 326 insertions, 106 deletions
diff --git a/recipes/llvm/llvm2.7/MOVLRPC.patch b/recipes/llvm/llvm2.7/MOVLRPC.patch deleted file mode 100644 index c00c4b1425..0000000000 --- a/recipes/llvm/llvm2.7/MOVLRPC.patch +++ /dev/null @@ -1,106 +0,0 @@ -Index: llvm/lib/Target/ARM/ARMISelLowering.cpp -=================================================================== ---- llvm.orig/lib/Target/ARM/ARMISelLowering.cpp 2010-07-11 12:57:59.000000000 +0200 -+++ llvm/lib/Target/ARM/ARMISelLowering.cpp 2010-07-11 22:07:28.000000000 +0200 -@@ -560,6 +560,7 @@ - case ARMISD::BR_JT: return "ARMISD::BR_JT"; - case ARMISD::BR2_JT: return "ARMISD::BR2_JT"; - case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG"; -+ case ARMISD::MOVLRPC: return "ARMISD::MOVLRPC"; - case ARMISD::PIC_ADD: return "ARMISD::PIC_ADD"; - case ARMISD::CMP: return "ARMISD::CMP"; - case ARMISD::CMPZ: return "ARMISD::CMPZ"; -@@ -1288,6 +1289,14 @@ - // implicit def LR - LR mustn't be allocated as GRP:$dst of CALL_NOLINK - Chain = DAG.getCopyToReg(Chain, dl, ARM::LR, DAG.getUNDEF(MVT::i32),InFlag); - InFlag = Chain.getValue(1); -+ -+ if(!isTailCall){ -+ // explicit copy PC to LR and chain flag it to the call. -+ Chain = DAG.getNode(ARMISD::MOVLRPC, dl, -+ DAG.getVTList(MVT::Other, MVT::Flag), -+ Chain, InFlag); -+ InFlag = Chain.getValue(1); -+ } - } - - std::vector<SDValue> Ops; -Index: llvm/lib/Target/ARM/ARMISelLowering.h -=================================================================== ---- llvm.orig/lib/Target/ARM/ARMISelLowering.h 2010-07-11 12:57:59.000000000 +0200 -+++ llvm/lib/Target/ARM/ARMISelLowering.h 2010-07-11 12:59:02.000000000 +0200 -@@ -42,6 +42,7 @@ - BR_JT, // Jumptable branch. - BR2_JT, // Jumptable branch (2 level - jumptable entry is a jump). - RET_FLAG, // Return with a flag operand. -+ MOVLRPC, // Store return address PC in LR before call - flag before CALL_NOLINK - - PIC_ADD, // Add with a PC operand and a PIC label. - -Index: llvm/lib/Target/ARM/ARMInstrInfo.td -=================================================================== ---- llvm.orig/lib/Target/ARM/ARMInstrInfo.td 2010-07-11 12:57:59.000000000 +0200 -+++ llvm/lib/Target/ARM/ARMInstrInfo.td 2010-07-11 12:59:02.000000000 +0200 -@@ -74,6 +74,9 @@ - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, - SDNPVariadic]>; - -+def ARMmovlrpc : SDNode<"ARMISD::MOVLRPC", SDTNone, -+ [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; -+ - def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag]>; - -@@ -674,6 +677,16 @@ - [(ARMcallseq_start timm:$amt)]>; - } - -+let Defs = [LR], hasSideEffects = 1 in -+def MOVLRPC : AI<(outs), (ins), BrMiscFrm, IIC_Br, -+ "mov", "\tlr, pc", [(ARMmovlrpc)]>, -+ Requires<[IsARM]> { -+ let Inst{11-0} = 0b000000001111; -+ let Inst{15-12} = 0b1110; -+ let Inst{19-16} = 0b0000; -+ let Inst{27-20} = 0b00011010; -+} -+ - def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "", - [/* For disassembly only; pattern left blank */]>, - Requires<[IsARM, HasV6T2]> { -@@ -962,7 +975,7 @@ - // ARMv4T - // Note: Restrict $func to the tGPR regclass to prevent it being in LR. - def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops), -- IIC_Br, "mov\tlr, pc\n\tbx\t$func", -+ IIC_Br, "bx\t$func", - [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsARM, HasV4T, IsNotDarwin]> { - let Inst{7-4} = 0b0001; -@@ -972,7 +985,7 @@ - - // ARMv4 - def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops), -- IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func", -+ IIC_Br, "mov\tpc, $func", - [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsARM, NoV4T, IsNotDarwin]> { - let Inst{11-4} = 0b00000000; -@@ -1011,7 +1024,7 @@ - // ARMv4T - // Note: Restrict $func to the tGPR regclass to prevent it being in LR. - def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops), -- IIC_Br, "mov\tlr, pc\n\tbx\t$func", -+ IIC_Br, "bx\t$func", - [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsARM, HasV4T, IsDarwin]> { - let Inst{7-4} = 0b0001; -@@ -1021,7 +1034,7 @@ - - // ARMv4 - def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops), -- IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func", -+ IIC_Br, "mov\tpc, $func", - [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsARM, NoV4T, IsDarwin]> { - let Inst{11-4} = 0b00000000; diff --git a/recipes/llvm/llvm2.7/r104587-MOVimm32.patch b/recipes/llvm/llvm2.7/r104587-MOVimm32.patch new file mode 100644 index 0000000000..76cbfe8376 --- /dev/null +++ b/recipes/llvm/llvm2.7/r104587-MOVimm32.patch @@ -0,0 +1,190 @@ +Index: llvm2.7/lib/Target/ARM/ARMJITInfo.cpp +=================================================================== +--- llvm2.7.org/lib/Target/ARM/ARMJITInfo.cpp (revision 104586) ++++ llvm2.7/lib/Target/ARM/ARMJITInfo.cpp (revision 104587) +@@ -318,6 +318,18 @@ + *((intptr_t*)RelocPos) |= ResultPtr; + break; + } ++ case ARM::reloc_arm_movw: { ++ ResultPtr = ResultPtr & 0xFFFF; ++ *((intptr_t*)RelocPos) |= ResultPtr & 0xFFF; ++ *((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16; ++ break; + } ++ case ARM::reloc_arm_movt: { ++ ResultPtr = (ResultPtr >> 16) & 0xFFFF; ++ *((intptr_t*)RelocPos) |= ResultPtr & 0xFFF; ++ *((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16; ++ break; ++ } ++ } + } + } +Index: llvm2.7/lib/Target/ARM/ARMCodeEmitter.cpp +=================================================================== +--- llvm2.7.org/lib/Target/ARM/ARMCodeEmitter.cpp (revision 104586) ++++ llvm2.7/lib/Target/ARM/ARMCodeEmitter.cpp (revision 104587) +@@ -88,6 +88,7 @@ + void emitWordLE(unsigned Binary); + void emitDWordLE(uint64_t Binary); + void emitConstPoolInstruction(const MachineInstr &MI); ++ void emitMOVi32immInstruction(const MachineInstr &MI); + void emitMOVi2piecesInstruction(const MachineInstr &MI); + void emitLEApcrelJTInstruction(const MachineInstr &MI); + void emitPseudoMoveInstruction(const MachineInstr &MI); +@@ -145,6 +146,15 @@ + return getMachineOpValue(MI, MI.getOperand(OpIdx)); + } + ++ /// getMovi32Value - Return binary encoding of operand for movw/movt. If the ++ /// machine operand requires relocation, record the relocation and return zero. ++ unsigned getMovi32Value(const MachineInstr &MI,const MachineOperand &MO, ++ unsigned Reloc); ++ unsigned getMovi32Value(const MachineInstr &MI, unsigned OpIdx, ++ unsigned Reloc) { ++ return getMovi32Value(MI, MI.getOperand(OpIdx), Reloc); ++ } ++ + /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. + /// + unsigned getShiftOp(unsigned Imm) const ; +@@ -217,6 +227,31 @@ + return 0; + } + ++/// getMovi32Value - Return binary encoding of operand for movw/movt. If the ++/// machine operand requires relocation, record the relocation and return zero. ++unsigned ARMCodeEmitter::getMovi32Value(const MachineInstr &MI, ++ const MachineOperand &MO, ++ unsigned Reloc) { ++ assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw)) ++ && "Relocation to this function should be for movt or movw"); ++ ++ if (MO.isImm()) ++ return static_cast<unsigned>(MO.getImm()); ++ else if (MO.isGlobal()) ++ emitGlobalAddress(MO.getGlobal(), Reloc, true, false); ++ else if (MO.isSymbol()) ++ emitExternalSymbolAddress(MO.getSymbolName(), Reloc); ++ else if (MO.isMBB()) ++ emitMachineBasicBlock(MO.getMBB(), Reloc); ++ else { ++#ifndef NDEBUG ++ errs() << MO; ++#endif ++ llvm_unreachable("Unsupported operand type for movw/movt"); ++ } ++ return 0; ++} ++ + /// getMachineOpValue - Return binary encoding of operand. If the machine + /// operand requires relocation, record the relocation and return zero. + unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI, +@@ -438,6 +473,42 @@ + } + } + ++void ARMCodeEmitter::emitMOVi32immInstruction(const MachineInstr &MI) { ++ const MachineOperand &MO0 = MI.getOperand(0); ++ const MachineOperand &MO1 = MI.getOperand(1); ++ ++ // Emit the 'movw' instruction. ++ unsigned Binary = 0x30 << 20; // mov: Insts{27-20} = 0b00110000 ++ ++ unsigned Lo16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movw) & 0xFFFF; ++ ++ // Set the conditional execution predicate. ++ Binary |= II->getPredicate(&MI) << ARMII::CondShift; ++ ++ // Encode Rd. ++ Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift; ++ ++ // Encode imm16 as imm4:imm12 ++ Binary |= Lo16 & 0xFFF; // Insts{11-0} = imm12 ++ Binary |= ((Lo16 >> 12) & 0xF) << 16; // Insts{19-16} = imm4 ++ emitWordLE(Binary); ++ ++ unsigned Hi16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movt) >> 16; ++ // Emit the 'movt' instruction. ++ Binary = 0x34 << 20; // movt: Insts{27-20} = 0b00110100 ++ ++ // Set the conditional execution predicate. ++ Binary |= II->getPredicate(&MI) << ARMII::CondShift; ++ ++ // Encode Rd. ++ Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift; ++ ++ // Encode imm16 as imm4:imm1, same as movw above. ++ Binary |= Hi16 & 0xFFF; ++ Binary |= ((Hi16 >> 12) & 0xF) << 16; ++ emitWordLE(Binary); ++} ++ + void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) { + const MachineOperand &MO0 = MI.getOperand(0); + const MachineOperand &MO1 = MI.getOperand(1); +@@ -557,7 +628,6 @@ + switch (Opcode) { + default: + llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction"); +- // FIXME: Add support for MOVimm32. + case TargetOpcode::INLINEASM: { + // We allow inline assembler nodes with empty bodies - they can + // implicitly define registers, which is ok for JIT. +@@ -604,6 +674,11 @@ + emitMiscLoadStoreInstruction(MI, ARM::PC); + break; + } ++ ++ case ARM::MOVi32imm: ++ emitMOVi32immInstruction(MI); ++ break; ++ + case ARM::MOVi2pieces: + // Two instructions to materialize a constant. + emitMOVi2piecesInstruction(MI); +@@ -729,6 +804,24 @@ + Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd) + << ARMII::RegRdShift); + ++ if (TID.Opcode == ARM::MOVi16) { ++ // Get immediate from MI. ++ unsigned Lo16 = getMovi32Value(MI, MI.getOperand(OpIdx), ++ ARM::reloc_arm_movw); ++ // Encode imm which is the same as in emitMOVi32immInstruction(). ++ Binary |= Lo16 & 0xFFF; ++ Binary |= ((Lo16 >> 12) & 0xF) << 16; ++ emitWordLE(Binary); ++ return; ++ } else if(TID.Opcode == ARM::MOVTi16) { ++ unsigned Hi16 = (getMovi32Value(MI, MI.getOperand(OpIdx), ++ ARM::reloc_arm_movt) >> 16); ++ Binary |= Hi16 & 0xFFF; ++ Binary |= ((Hi16 >> 12) & 0xF) << 16; ++ emitWordLE(Binary); ++ return; ++ } ++ + // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. + if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) + ++OpIdx; +Index: llvm2.7/lib/Target/ARM/ARMRelocations.h +=================================================================== +--- llvm2.7.org/lib/Target/ARM/ARMRelocations.h (revision 104586) ++++ llvm2.7/lib/Target/ARM/ARMRelocations.h (revision 104587) +@@ -47,7 +47,13 @@ + reloc_arm_pic_jt, + + // reloc_arm_branch - Branch address relocation. +- reloc_arm_branch ++ reloc_arm_branch, ++ ++ // reloc_arm_movt - MOVT immediate relocation. ++ reloc_arm_movt, ++ ++ // reloc_arm_movw - MOVW immediate relocation. ++ reloc_arm_movw + }; + } + } diff --git a/recipes/llvm/llvm2.7/r97745-llvmPR6480.patch b/recipes/llvm/llvm2.7/r97745-llvmPR6480.patch new file mode 100644 index 0000000000..7ca5eef212 --- /dev/null +++ b/recipes/llvm/llvm2.7/r97745-llvmPR6480.patch @@ -0,0 +1,75 @@ +Index: llvm2.7/test/CodeGen/ARM/2010-03-04-stm-undef-addr.ll +=================================================================== +--- llvm2.7.org/test/CodeGen/ARM/2010-03-04-stm-undef-addr.ll (revision 0) ++++ llvm2.7/test/CodeGen/ARM/2010-03-04-stm-undef-addr.ll (revision 97745) +@@ -0,0 +1,54 @@ ++; RUN: llc < %s -march=arm ++ ++define void @"java.lang.String::getChars"([84 x i8]* %method, i32 %base_pc, [788 x i8]* %thread) { ++ %1 = sub i32 undef, 48 ; <i32> [#uses=1] ++ br i1 undef, label %stack_overflow, label %no_overflow ++ ++stack_overflow: ; preds = %0 ++ unreachable ++ ++no_overflow: ; preds = %0 ++ %frame = inttoptr i32 %1 to [17 x i32]* ; <[17 x i32]*> [#uses=4] ++ %2 = load i32* null ; <i32> [#uses=2] ++ %3 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 14 ; <i32*> [#uses=1] ++ %4 = load i32* %3 ; <i32> [#uses=2] ++ %5 = load [8 x i8]** undef ; <[8 x i8]*> [#uses=2] ++ br i1 undef, label %bci_13, label %bci_4 ++ ++bci_13: ; preds = %no_overflow ++ br i1 undef, label %bci_30, label %bci_21 ++ ++bci_30: ; preds = %bci_13 ++ %6 = icmp sle i32 %2, %4 ; <i1> [#uses=1] ++ br i1 %6, label %bci_46, label %bci_35 ++ ++bci_46: ; preds = %bci_30 ++ store [84 x i8]* %method, [84 x i8]** undef ++ br i1 false, label %no_exception, label %exception ++ ++exception: ; preds = %bci_46 ++ ret void ++ ++no_exception: ; preds = %bci_46 ++ ret void ++ ++bci_35: ; preds = %bci_30 ++ %7 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 15 ; <i32*> [#uses=1] ++ store i32 %2, i32* %7 ++ %8 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 14 ; <i32*> [#uses=1] ++ store i32 %4, i32* %8 ++ %9 = getelementptr inbounds [17 x i32]* %frame, i32 0, i32 13 ; <i32*> [#uses=1] ++ %10 = bitcast i32* %9 to [8 x i8]** ; <[8 x i8]**> [#uses=1] ++ store [8 x i8]* %5, [8 x i8]** %10 ++ call void inttoptr (i32 13839116 to void ([788 x i8]*, i32)*)([788 x i8]* %thread, i32 7) ++ ret void ++ ++bci_21: ; preds = %bci_13 ++ ret void ++ ++bci_4: ; preds = %no_overflow ++ store [8 x i8]* %5, [8 x i8]** undef ++ store i32 undef, i32* undef ++ call void inttoptr (i32 13839116 to void ([788 x i8]*, i32)*)([788 x i8]* %thread, i32 7) ++ ret void ++} +Index: llvm2.7/lib/Target/ARM/ARMLoadStoreOptimizer.cpp +=================================================================== +--- llvm2.7.org/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (revision 97744) ++++ llvm2.7/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (revision 97745) +@@ -761,6 +761,11 @@ + MI->getOperand(0).isUndef()) + return false; + ++ // Likewise don't mess with references to undefined addresses. ++ if (MI->getNumOperands() > 1 && MI->getOperand(1).isReg() && ++ MI->getOperand(1).isUndef()) ++ return false; ++ + int Opcode = MI->getOpcode(); + switch (Opcode) { + default: break; diff --git a/recipes/llvm/llvm2.7/rawMOVLRPC.patch b/recipes/llvm/llvm2.7/rawMOVLRPC.patch new file mode 100644 index 0000000000..ec642155ef --- /dev/null +++ b/recipes/llvm/llvm2.7/rawMOVLRPC.patch @@ -0,0 +1,61 @@ +Index: llvm/lib/Target/ARM/ARMInstrInfo.td +=================================================================== +--- llvm.orig/lib/Target/ARM/ARMInstrInfo.td 2010-07-13 17:41:01.000000000 +0200 ++++ llvm/lib/Target/ARM/ARMInstrInfo.td 2010-07-19 17:11:19.000000000 +0200 +@@ -961,7 +961,7 @@ + + // ARMv4T + // Note: Restrict $func to the tGPR regclass to prevent it being in LR. +- def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops), ++ def BX : PseudoInst<(outs), (ins tGPR:$func, variable_ops), + IIC_Br, "mov\tlr, pc\n\tbx\t$func", + [(ARMcall_nolink tGPR:$func)]>, + Requires<[IsARM, HasV4T, IsNotDarwin]> { +@@ -971,7 +971,7 @@ + } + + // ARMv4 +- def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops), ++ def BMOVPCRX : PseudoInst<(outs), (ins tGPR:$func, variable_ops), + IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func", + [(ARMcall_nolink tGPR:$func)]>, + Requires<[IsARM, NoV4T, IsNotDarwin]> { +@@ -1010,7 +1010,7 @@ + + // ARMv4T + // Note: Restrict $func to the tGPR regclass to prevent it being in LR. +- def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops), ++ def BXr9 : PseudoInst<(outs), (ins tGPR:$func, variable_ops), + IIC_Br, "mov\tlr, pc\n\tbx\t$func", + [(ARMcall_nolink tGPR:$func)]>, + Requires<[IsARM, HasV4T, IsDarwin]> { +@@ -1020,7 +1020,7 @@ + } + + // ARMv4 +- def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops), ++ def BMOVPCRXr9 : PseudoInst<(outs), (ins tGPR:$func, variable_ops), + IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func", + [(ARMcall_nolink tGPR:$func)]>, + Requires<[IsARM, NoV4T, IsDarwin]> { +Index: llvm/lib/Target/ARM/ARMCodeEmitter.cpp +=================================================================== +--- llvm.orig/lib/Target/ARM/ARMCodeEmitter.cpp 2010-07-13 17:41:01.000000000 +0200 ++++ llvm/lib/Target/ARM/ARMCodeEmitter.cpp 2010-07-19 17:20:26.000000000 +0200 +@@ -654,6 +654,16 @@ + switch (Opcode) { + default: + llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction"); ++ case ARM::BX: ++ case ARM::BMOVPCRX: ++ case ARM::BXr9: ++ case ARM::BMOVPCRXr9: { ++ // First emit mov lr, pc ++ emitWordLE(0xe1a0e00f); ++ // and then emit the branch. ++ emitMiscBranchInstruction(MI); ++ break; ++ } + case TargetOpcode::INLINEASM: { + // We allow inline assembler nodes with empty bodies - they can + // implicitly define registers, which is ok for JIT. |