Index: lib/Target/Mips/MipsLongBranch.cpp =================================================================== --- lib/Target/Mips/MipsLongBranch.cpp +++ lib/Target/Mips/MipsLongBranch.cpp @@ -64,7 +64,7 @@ : MachineFunctionPass(ID), TM(tm), IsPIC(TM.getRelocationModel() == Reloc::PIC_), ABI(TM.getSubtarget().getTargetABI()), - LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : 9)) {} + LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 11 : 9)) {} virtual const char *getPassName() const { return "Mips Long Branch"; @@ -324,9 +324,7 @@ // $longbr: // daddiu $sp, $sp, -16 // sd $ra, 0($sp) - // lui64 $at, %highest($tgt - $baltgt) - // daddiu $at, $at, %higher($tgt - $baltgt) - // dsll $at, $at, 16 + // daddiu $at, $zero, 0 // daddiu $at, $at, %hi($tgt - $baltgt) // bal $baltgt // dsll $at, $at, 16 @@ -339,10 +337,31 @@ // $fallthrough: // - // TODO: %highest and %higher can have non-zero values only when the - // offset is greater than 4GB, which is highly unlikely. Replace - // them (and the following instructon that shifts $at by 16) with the - // instruction that sets $at to zero. + // Note that we optimized offset calculation by using + // + // daddiu $at, $zero, 0 + // + // instead of + // + // lui64 $at, %highest($tgt - $baltgt) + // daddiu $at, $at, %higher($tgt - $baltgt) + // dsll $at, $at, 16 + // + // It's safe to do this because %highest and %higher can have non-zero + // values only when the offset is greater than 4GB, which is highly + // unlikely, if not impossible when compiling a single function. + // + // Note that this will work even if the offset is negative, because + // of the +1 modification that's added in that case. For example, if the + // offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is + // + // 0xFFFFFFFFFFF00000 + 0x80008000 = 0x000000007FF08000 + // + // and the bits [47:32] are zero. For %highest + // + // 0xFFFFFFFFFFF00000 + 0x800080008000 = 0x000080007FF08000 + // + // and the bits [63:48] are zero. Pos = LongBrMBB->begin(); @@ -350,12 +369,8 @@ .addReg(Mips::SP_64).addImm(-16); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64) .addReg(Mips::SP_64).addImm(0); - BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi64), Mips::AT_64) - .addMBB(TgtMBB).addMBB(BalTgtMBB); - BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64) - .addReg(Mips::AT_64).addMBB(TgtMBB, MipsII::MO_HIGHER).addMBB(BalTgtMBB); - BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) - .addReg(Mips::AT_64).addImm(16); + BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::AT_64) + .addReg(Mips::ZERO_64).addImm(0); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64) .addReg(Mips::AT_64).addMBB(TgtMBB, MipsII::MO_ABS_HI).addMBB(BalTgtMBB); Index: test/CodeGen/Mips/longbranch.ll =================================================================== --- test/CodeGen/Mips/longbranch.ll +++ test/CodeGen/Mips/longbranch.ll @@ -76,10 +76,8 @@ ; N64: daddiu $sp, $sp, -16 ; N64: sd $ra, 0($sp) -; N64: lui $1, %highest(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]])) -; N64: daddiu $1, $1, %higher(($[[BB2]])-($[[BB1]])) -; N64: dsll $1, $1, 16 -; N64: daddiu $1, $1, %hi(($[[BB2]])-($[[BB1]])) +; N64: daddiu $1, $zero, 0 +; N64: daddiu $1, $1, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]])) ; N64: bal $[[BB1]] ; N64: dsll $1, $1, 16 ; N64: $[[BB1]]: