diff options
Diffstat (limited to 'contrib/llvm/patches')
-rw-r--r-- | contrib/llvm/patches/README.TXT | 8 | ||||
-rw-r--r-- | contrib/llvm/patches/patch-01-freebsd-kprintf.diff | 10 | ||||
-rw-r--r-- | contrib/llvm/patches/patch-07-llvm-r227752-boot2-shrink.diff | 10 | ||||
-rw-r--r-- | contrib/llvm/patches/patch-08-llvm-r227089-fix-mips-i128.diff | 1950 | ||||
-rw-r--r-- | contrib/llvm/patches/patch-08-llvm-r230348-arm-fix-bad-ha.diff (renamed from contrib/llvm/patches/patch-10-llvm-r230348-arm-fix-bad-ha.diff) | 8 | ||||
-rw-r--r-- | contrib/llvm/patches/patch-09-clang-r227115-constantarraytype.diff (renamed from contrib/llvm/patches/patch-12-clang-r227115-constantarraytype.diff) | 0 | ||||
-rw-r--r-- | contrib/llvm/patches/patch-09-llvm-r230058-indirectbrs-assert.diff | 55 | ||||
-rw-r--r-- | contrib/llvm/patches/patch-11-llvm-r231227-aarch64-tls-relocs.diff | 811 | ||||
-rw-r--r-- | contrib/llvm/patches/patch-13-llvm-r229911-uleb128-commas.diff | 77 |
9 files changed, 18 insertions, 2911 deletions
diff --git a/contrib/llvm/patches/README.TXT b/contrib/llvm/patches/README.TXT index f3fc208..7bc26d2 100644 --- a/contrib/llvm/patches/README.TXT +++ b/contrib/llvm/patches/README.TXT @@ -1,11 +1,11 @@ This is a set of individual patches, which contain all the customizations to llvm/clang currently in the FreeBSD base system. These can be applied in -alphabetical order to a pristine llvm/clang 3.6.0 source tree, for example by +alphabetical order to a pristine llvm/clang 3.6.1 source tree, for example by doing: -svn co https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_360/final llvm-3.6.0 -svn co https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_360/final llvm-3.6.0/tools/clang -cd llvm-3.6.0 +svn co https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_361/final llvm-3.6.1 +svn co https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_361/final llvm-3.6.1/tools/clang +cd llvm-3.6.1 for p in /usr/src/contrib/llvm/patches/patch-*.diff; do patch -p0 -f -F0 -E -i $p -s || break done diff --git a/contrib/llvm/patches/patch-01-freebsd-kprintf.diff b/contrib/llvm/patches/patch-01-freebsd-kprintf.diff index cccfedf..252b4cd 100644 --- a/contrib/llvm/patches/patch-01-freebsd-kprintf.diff +++ b/contrib/llvm/patches/patch-01-freebsd-kprintf.diff @@ -44,7 +44,7 @@ Index: tools/clang/include/clang/Sema/Sema.h =================================================================== --- tools/clang/include/clang/Sema/Sema.h +++ tools/clang/include/clang/Sema/Sema.h -@@ -8566,6 +8566,7 @@ class Sema { +@@ -8567,6 +8567,7 @@ class Sema { FST_Strftime, FST_Strfmon, FST_Kprintf, @@ -230,7 +230,7 @@ Index: tools/clang/lib/Sema/SemaChecking.cpp =================================================================== --- tools/clang/lib/Sema/SemaChecking.cpp +++ tools/clang/lib/Sema/SemaChecking.cpp -@@ -2584,6 +2584,7 @@ Sema::FormatStringType Sema::GetFormatStringType(c +@@ -2603,6 +2603,7 @@ Sema::FormatStringType Sema::GetFormatStringType(c .Case("strftime", FST_Strftime) .Case("strfmon", FST_Strfmon) .Cases("kprintf", "cmn_err", "vcmn_err", "zcmn_err", FST_Kprintf) @@ -238,7 +238,7 @@ Index: tools/clang/lib/Sema/SemaChecking.cpp .Default(FST_Unknown); } -@@ -3365,6 +3366,43 @@ CheckPrintfHandler::HandlePrintfSpecifier(const an +@@ -3384,6 +3385,43 @@ CheckPrintfHandler::HandlePrintfSpecifier(const an CoveredArgs.set(argIndex); } @@ -282,7 +282,7 @@ Index: tools/clang/lib/Sema/SemaChecking.cpp // Check for using an Objective-C specific conversion specifier // in a non-ObjC literal. if (!ObjCContext && CS.isObjCArg()) { -@@ -3988,7 +4026,8 @@ void Sema::CheckFormatString(const StringLiteral * +@@ -4007,7 +4045,8 @@ void Sema::CheckFormatString(const StringLiteral * return; } @@ -292,7 +292,7 @@ Index: tools/clang/lib/Sema/SemaChecking.cpp CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg, numDataArgs, (Type == FST_NSString), Str, HasVAListArg, Args, format_idx, -@@ -3996,7 +4035,8 @@ void Sema::CheckFormatString(const StringLiteral * +@@ -4015,7 +4054,8 @@ void Sema::CheckFormatString(const StringLiteral * if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen, getLangOpts(), diff --git a/contrib/llvm/patches/patch-07-llvm-r227752-boot2-shrink.diff b/contrib/llvm/patches/patch-07-llvm-r227752-boot2-shrink.diff index d5650f7..57e16d7 100644 --- a/contrib/llvm/patches/patch-07-llvm-r227752-boot2-shrink.diff +++ b/contrib/llvm/patches/patch-07-llvm-r227752-boot2-shrink.diff @@ -596,7 +596,7 @@ Index: lib/Target/X86/X86FrameLowering.cpp static unsigned getLEArOpcode(unsigned IsLP64) { return IsLP64 ? X86::LEA64r : X86::LEA32r; } -@@ -1848,100 +1865,6 @@ void X86FrameLowering::adjustForHiPEPrologue(Machi +@@ -1882,100 +1899,6 @@ void X86FrameLowering::adjustForHiPEPrologue(Machi #endif } @@ -697,7 +697,7 @@ Index: lib/Target/X86/X86FrameLowering.cpp void X86FrameLowering:: eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { -@@ -1956,7 +1879,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, +@@ -1990,7 +1913,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, bool IsLP64 = STI.isTarget64BitLP64(); DebugLoc DL = I->getDebugLoc(); uint64_t Amount = !reserveCallFrame ? I->getOperand(0).getImm() : 0; @@ -706,7 +706,7 @@ Index: lib/Target/X86/X86FrameLowering.cpp I = MBB.erase(I); if (!reserveCallFrame) { -@@ -1976,24 +1899,18 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, +@@ -2010,24 +1933,18 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign; MachineInstr *New = nullptr; @@ -740,7 +740,7 @@ Index: lib/Target/X86/X86FrameLowering.cpp unsigned Opc = getADDriOpcode(IsLP64, Amount); New = BuildMI(MF, DL, TII.get(Opc), StackPtr) .addReg(StackPtr).addImm(Amount); -@@ -2011,13 +1928,13 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, +@@ -2045,13 +1962,13 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, return; } @@ -761,7 +761,7 @@ Index: lib/Target/X86/X86FrameLowering.h =================================================================== --- lib/Target/X86/X86FrameLowering.h +++ lib/Target/X86/X86FrameLowering.h -@@ -64,6 +64,8 @@ class X86FrameLowering : public TargetFrameLowerin +@@ -66,6 +66,8 @@ class X86FrameLowering : public TargetFrameLowerin bool hasFP(const MachineFunction &MF) const override; bool hasReservedCallFrame(const MachineFunction &MF) const override; diff --git a/contrib/llvm/patches/patch-08-llvm-r227089-fix-mips-i128.diff b/contrib/llvm/patches/patch-08-llvm-r227089-fix-mips-i128.diff deleted file mode 100644 index 00a44f5..0000000 --- a/contrib/llvm/patches/patch-08-llvm-r227089-fix-mips-i128.diff +++ /dev/null @@ -1,1950 +0,0 @@ -Pull in r227087 from upstream llvm trunk (by Vasileios Kalintiris): - - [mips] Add tests for bitwise binary and integer arithmetic operators. - - Reviewers: dsanders - - Subscribers: llvm-commits - - Differential Revision: http://reviews.llvm.org/D7125 - -Pull in r227089 from upstream llvm trunk (by Vasileios Kalintiris): - - [mips] Enable arithmetic and binary operations for the i128 data type. - - Summary: - This patch adds support for some operations that were missing from - 128-bit integer types (add/sub/mul/sdiv/udiv... etc.). With these - changes we can support the __int128_t and __uint128_t data types - from C/C++. - - Depends on D7125 - - Reviewers: dsanders - - Subscribers: llvm-commits - - Differential Revision: http://reviews.llvm.org/D7143 - -This fixes "error in backend" messages, when compiling parts of -compiler-rt using 128-bit integer types for mips64. - -Reported by: sbruno -PR: 197259 - -Introduced here: http://svnweb.freebsd.org/changeset/base/278367 - -Index: lib/Target/Mips/Mips64InstrInfo.td -=================================================================== ---- lib/Target/Mips/Mips64InstrInfo.td -+++ lib/Target/Mips/Mips64InstrInfo.td -@@ -440,6 +440,16 @@ def : MipsPat<(i64 (sext_inreg GPR64:$src, i32)), - // bswap MipsPattern - def : MipsPat<(bswap GPR64:$rt), (DSHD (DSBH GPR64:$rt))>; - -+// Carry pattern -+def : MipsPat<(subc GPR64:$lhs, GPR64:$rhs), -+ (DSUBu GPR64:$lhs, GPR64:$rhs)>; -+let AdditionalPredicates = [NotDSP] in { -+ def : MipsPat<(addc GPR64:$lhs, GPR64:$rhs), -+ (DADDu GPR64:$lhs, GPR64:$rhs)>; -+ def : MipsPat<(addc GPR64:$lhs, immSExt16:$imm), -+ (DADDiu GPR64:$lhs, imm:$imm)>; -+} -+ - //===----------------------------------------------------------------------===// - // Instruction aliases - //===----------------------------------------------------------------------===// -Index: lib/Target/Mips/MipsISelLowering.cpp -=================================================================== ---- lib/Target/Mips/MipsISelLowering.cpp -+++ lib/Target/Mips/MipsISelLowering.cpp -@@ -261,6 +261,9 @@ MipsTargetLowering::MipsTargetLowering(const MipsT - setOperationAction(ISD::LOAD, MVT::i64, Custom); - setOperationAction(ISD::STORE, MVT::i64, Custom); - setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); -+ setOperationAction(ISD::SHL_PARTS, MVT::i64, Custom); -+ setOperationAction(ISD::SRA_PARTS, MVT::i64, Custom); -+ setOperationAction(ISD::SRL_PARTS, MVT::i64, Custom); - } - - if (!Subtarget.isGP64bit()) { -@@ -2017,10 +2020,11 @@ SDValue MipsTargetLowering::lowerATOMIC_FENCE(SDVa - SDValue MipsTargetLowering::lowerShiftLeftParts(SDValue Op, - SelectionDAG &DAG) const { - SDLoc DL(Op); -+ MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32; -+ - SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1); - SDValue Shamt = Op.getOperand(2); -- -- // if shamt < 32: -+ // if shamt < (VT.bits): - // lo = (shl lo, shamt) - // hi = (or (shl hi, shamt) (srl (srl lo, 1), ~shamt)) - // else: -@@ -2028,18 +2032,17 @@ SDValue MipsTargetLowering::lowerShiftLeftParts(SD - // hi = (shl lo, shamt[4:0]) - SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt, - DAG.getConstant(-1, MVT::i32)); -- SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, MVT::i32, Lo, -- DAG.getConstant(1, MVT::i32)); -- SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, MVT::i32, ShiftRight1Lo, -- Not); -- SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, MVT::i32, Hi, Shamt); -- SDValue Or = DAG.getNode(ISD::OR, DL, MVT::i32, ShiftLeftHi, ShiftRightLo); -- SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, MVT::i32, Lo, Shamt); -+ SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo, -+ DAG.getConstant(1, VT)); -+ SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, Not); -+ SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, Hi, Shamt); -+ SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo); -+ SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt); - SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt, - DAG.getConstant(0x20, MVT::i32)); -- Lo = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, -- DAG.getConstant(0, MVT::i32), ShiftLeftLo); -- Hi = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, ShiftLeftLo, Or); -+ Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, -+ DAG.getConstant(0, VT), ShiftLeftLo); -+ Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftLeftLo, Or); - - SDValue Ops[2] = {Lo, Hi}; - return DAG.getMergeValues(Ops, DL); -@@ -2050,8 +2053,9 @@ SDValue MipsTargetLowering::lowerShiftRightParts(S - SDLoc DL(Op); - SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1); - SDValue Shamt = Op.getOperand(2); -+ MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32; - -- // if shamt < 32: -+ // if shamt < (VT.bits): - // lo = (or (shl (shl hi, 1), ~shamt) (srl lo, shamt)) - // if isSRA: - // hi = (sra hi, shamt) -@@ -2066,21 +2070,19 @@ SDValue MipsTargetLowering::lowerShiftRightParts(S - // hi = 0 - SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt, - DAG.getConstant(-1, MVT::i32)); -- SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL, DL, MVT::i32, Hi, -- DAG.getConstant(1, MVT::i32)); -- SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, MVT::i32, ShiftLeft1Hi, Not); -- SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, MVT::i32, Lo, Shamt); -- SDValue Or = DAG.getNode(ISD::OR, DL, MVT::i32, ShiftLeftHi, ShiftRightLo); -- SDValue ShiftRightHi = DAG.getNode(IsSRA ? ISD::SRA : ISD::SRL, DL, MVT::i32, -- Hi, Shamt); -+ SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL, DL, VT, Hi, -+ DAG.getConstant(1, VT)); -+ SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, ShiftLeft1Hi, Not); -+ SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, Lo, Shamt); -+ SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo); -+ SDValue ShiftRightHi = DAG.getNode(IsSRA ? ISD::SRA : ISD::SRL, -+ DL, VT, Hi, Shamt); - SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt, - DAG.getConstant(0x20, MVT::i32)); -- SDValue Shift31 = DAG.getNode(ISD::SRA, DL, MVT::i32, Hi, -- DAG.getConstant(31, MVT::i32)); -- Lo = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, ShiftRightHi, Or); -- Hi = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, -- IsSRA ? Shift31 : DAG.getConstant(0, MVT::i32), -- ShiftRightHi); -+ SDValue Shift31 = DAG.getNode(ISD::SRA, DL, VT, Hi, DAG.getConstant(31, VT)); -+ Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftRightHi, Or); -+ Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, -+ IsSRA ? Shift31 : DAG.getConstant(0, VT), ShiftRightHi); - - SDValue Ops[2] = {Lo, Hi}; - return DAG.getMergeValues(Ops, DL); -Index: lib/Target/Mips/MipsSEISelDAGToDAG.cpp -=================================================================== ---- lib/Target/Mips/MipsSEISelDAGToDAG.cpp -+++ lib/Target/Mips/MipsSEISelDAGToDAG.cpp -@@ -236,13 +236,31 @@ SDNode *MipsSEDAGToDAGISel::selectAddESubE(unsigne - (Opc == ISD::SUBC || Opc == ISD::SUBE)) && - "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn"); - -+ unsigned SLTuOp = Mips::SLTu, ADDuOp = Mips::ADDu; -+ if (Subtarget->isGP64bit()) { -+ SLTuOp = Mips::SLTu64; -+ ADDuOp = Mips::DADDu; -+ } -+ - SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) }; - SDValue LHS = Node->getOperand(0), RHS = Node->getOperand(1); - EVT VT = LHS.getValueType(); - -- SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, DL, VT, Ops); -- SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, DL, VT, -+ SDNode *Carry = CurDAG->getMachineNode(SLTuOp, DL, VT, Ops); -+ -+ if (Subtarget->isGP64bit()) { -+ // On 64-bit targets, sltu produces an i64 but our backend currently says -+ // that SLTu64 produces an i32. We need to fix this in the long run but for -+ // now, just make the DAG type-correct by asserting the upper bits are zero. -+ Carry = CurDAG->getMachineNode(Mips::SUBREG_TO_REG, DL, VT, -+ CurDAG->getTargetConstant(0, VT), -+ SDValue(Carry, 0), -+ CurDAG->getTargetConstant(Mips::sub_32, VT)); -+ } -+ -+ SDNode *AddCarry = CurDAG->getMachineNode(ADDuOp, DL, VT, - SDValue(Carry, 0), RHS); -+ - return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS, - SDValue(AddCarry, 0)); - } -@@ -641,7 +659,8 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selec - - case ISD::SUBE: { - SDValue InFlag = Node->getOperand(2); -- Result = selectAddESubE(Mips::SUBu, InFlag, InFlag.getOperand(0), DL, Node); -+ unsigned Opc = Subtarget->isGP64bit() ? Mips::DSUBu : Mips::SUBu; -+ Result = selectAddESubE(Opc, InFlag, InFlag.getOperand(0), DL, Node); - return std::make_pair(true, Result); - } - -@@ -649,7 +668,8 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selec - if (Subtarget->hasDSP()) // Select DSP instructions, ADDSC and ADDWC. - break; - SDValue InFlag = Node->getOperand(2); -- Result = selectAddESubE(Mips::ADDu, InFlag, InFlag.getValue(0), DL, Node); -+ unsigned Opc = Subtarget->isGP64bit() ? Mips::DADDu : Mips::ADDu; -+ Result = selectAddESubE(Opc, InFlag, InFlag.getValue(0), DL, Node); - return std::make_pair(true, Result); - } - -Index: lib/Target/Mips/MipsSEISelLowering.cpp -=================================================================== ---- lib/Target/Mips/MipsSEISelLowering.cpp -+++ lib/Target/Mips/MipsSEISelLowering.cpp -@@ -122,6 +122,8 @@ MipsSETargetLowering::MipsSETargetLowering(const M - setOperationAction(ISD::MUL, MVT::i64, Custom); - - if (Subtarget.isGP64bit()) { -+ setOperationAction(ISD::SMUL_LOHI, MVT::i64, Custom); -+ setOperationAction(ISD::UMUL_LOHI, MVT::i64, Custom); - setOperationAction(ISD::MULHS, MVT::i64, Custom); - setOperationAction(ISD::MULHU, MVT::i64, Custom); - setOperationAction(ISD::SDIVREM, MVT::i64, Custom); -@@ -200,6 +202,8 @@ MipsSETargetLowering::MipsSETargetLowering(const M - if (Subtarget.hasMips64r6()) { - // MIPS64r6 replaces the accumulator-based multiplies with a three register - // instruction -+ setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); -+ setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); - setOperationAction(ISD::MUL, MVT::i64, Legal); - setOperationAction(ISD::MULHS, MVT::i64, Legal); - setOperationAction(ISD::MULHU, MVT::i64, Legal); -Index: test/CodeGen/Mips/llvm-ir/add.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/add.ll -+++ test/CodeGen/Mips/llvm-ir/add.ll -@@ -0,0 +1,115 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP64 -+ -+define signext i1 @add_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: add_i1: -+ -+ ; ALL: addu $[[T0:[0-9]+]], $4, $5 -+ ; ALL: sll $[[T0]], $[[T0]], 31 -+ ; ALL: sra $2, $[[T0]], 31 -+ -+ %r = add i1 %a, %b -+ ret i1 %r -+} -+ -+define signext i8 @add_i8(i8 signext %a, i8 signext %b) { -+entry: -+; ALL-LABEL: add_i8: -+ -+ ; NOT-R2-R6: addu $[[T0:[0-9]+]], $4, $5 -+ ; NOT-R2-R6: sll $[[T0]], $[[T0]], 24 -+ ; NOT-R2-R6: sra $2, $[[T0]], 24 -+ -+ ; R2-R6: addu $[[T0:[0-9]+]], $4, $5 -+ ; R2-R6: seb $2, $[[T0:[0-9]+]] -+ -+ %r = add i8 %a, %b -+ ret i8 %r -+} -+ -+define signext i16 @add_i16(i16 signext %a, i16 signext %b) { -+entry: -+; ALL-LABEL: add_i16: -+ -+ ; NOT-R2-R6: addu $[[T0:[0-9]+]], $4, $5 -+ ; NOT-R2-R6: sll $[[T0]], $[[T0]], 16 -+ ; NOT-R2-R6: sra $2, $[[T0]], 16 -+ -+ ; R2-R6: addu $[[T0:[0-9]+]], $4, $5 -+ ; R2-R6: seh $2, $[[T0:[0-9]+]] -+ -+ %r = add i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @add_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: add_i32: -+ -+ ; ALL: addu $2, $4, $5 -+ -+ %r = add i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @add_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: add_i64: -+ -+ ; GP32: addu $3, $5, $7 -+ ; GP32: sltu $[[T0:[0-9]+]], $3, $7 -+ ; GP32: addu $[[T1:[0-9]+]], $[[T0]], $6 -+ ; GP32: addu $2, $4, $[[T1]] -+ -+ ; GP64: daddu $2, $4, $5 -+ -+ %r = add i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @add_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: add_i128: -+ -+ ; GP32: lw $[[T0:[0-9]+]], 28($sp) -+ ; GP32: addu $[[T1:[0-9]+]], $7, $[[T0]] -+ ; GP32: sltu $[[T2:[0-9]+]], $[[T1]], $[[T0]] -+ ; GP32: lw $[[T3:[0-9]+]], 24($sp) -+ ; GP32: addu $[[T4:[0-9]+]], $[[T2]], $[[T3]] -+ ; GP32: addu $[[T5:[0-9]+]], $6, $[[T4]] -+ ; GP32: sltu $[[T6:[0-9]+]], $[[T5]], $[[T3]] -+ ; GP32: lw $[[T7:[0-9]+]], 20($sp) -+ ; GP32: addu $[[T8:[0-9]+]], $[[T6]], $[[T7]] -+ ; GP32: lw $[[T9:[0-9]+]], 16($sp) -+ ; GP32: addu $3, $5, $[[T8]] -+ ; GP32: sltu $[[T10:[0-9]+]], $3, $[[T7]] -+ ; GP32: addu $[[T11:[0-9]+]], $[[T10]], $[[T9]] -+ ; GP32: addu $2, $4, $[[T11]] -+ ; GP32: move $4, $[[T5]] -+ ; GP32: move $5, $[[T1]] -+ -+ ; GP64: daddu $3, $5, $7 -+ ; GP64: sltu $[[T0:[0-9]+]], $3, $7 -+ ; GP64: daddu $[[T1:[0-9]+]], $[[T0]], $6 -+ ; GP64: daddu $2, $4, $[[T1]] -+ -+ %r = add i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/and.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/and.ll -+++ test/CodeGen/Mips/llvm-ir/and.ll -@@ -0,0 +1,94 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+ -+define signext i1 @and_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: and_i1: -+ -+ ; ALL: and $2, $4, $5 -+ -+ %r = and i1 %a, %b -+ ret i1 %r -+} -+ -+define signext i8 @and_i8(i8 signext %a, i8 signext %b) { -+entry: -+; ALL-LABEL: and_i8: -+ -+ ; ALL: and $2, $4, $5 -+ -+ %r = and i8 %a, %b -+ ret i8 %r -+} -+ -+define signext i16 @and_i16(i16 signext %a, i16 signext %b) { -+entry: -+; ALL-LABEL: and_i16: -+ -+ ; ALL: and $2, $4, $5 -+ -+ %r = and i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @and_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: and_i32: -+ -+ ; GP32: and $2, $4, $5 -+ -+ ; GP64: and $[[T0:[0-9]+]], $4, $5 -+ ; GP64: sll $2, $[[T0]], 0 -+ -+ %r = and i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @and_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: and_i64: -+ -+ ; GP32: and $2, $4, $6 -+ ; GP32: and $3, $5, $7 -+ -+ ; GP64: and $2, $4, $5 -+ -+ %r = and i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @and_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: and_i128: -+ -+ ; GP32: lw $[[T0:[0-9]+]], 24($sp) -+ ; GP32: lw $[[T1:[0-9]+]], 20($sp) -+ ; GP32: lw $[[T2:[0-9]+]], 16($sp) -+ ; GP32: and $2, $4, $[[T2]] -+ ; GP32: and $3, $5, $[[T1]] -+ ; GP32: and $4, $6, $[[T0]] -+ ; GP32: lw $[[T3:[0-9]+]], 28($sp) -+ ; GP32: and $5, $7, $[[T3]] -+ -+ ; GP64: and $2, $4, $6 -+ ; GP64: and $3, $5, $7 -+ -+ %r = and i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/ashr.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/ashr.ll -+++ test/CodeGen/Mips/llvm-ir/ashr.ll -@@ -0,0 +1,188 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 \ -+; RUN: -check-prefix=M2 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -check-prefix=NOT-R2-R6 \ -+; RUN: -check-prefix=32R1-R2 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 \ -+; RUN: -check-prefix=32R1-R2 -check-prefix=R2-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 \ -+; RUN: -check-prefix=32R6 -check-prefix=R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=M3 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=64R6 -check-prefix=R2-R6 -+ -+define signext i1 @ashr_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: ashr_i1: -+ -+ ; ALL: move $2, $4 -+ -+ %r = ashr i1 %a, %b -+ ret i1 %r -+} -+ -+define signext i8 @ashr_i8(i8 signext %a, i8 signext %b) { -+entry: -+; ALL-LABEL: ashr_i8: -+ -+ ; FIXME: The andi instruction is redundant. -+ ; ALL: andi $[[T0:[0-9]+]], $5, 255 -+ ; ALL: srav $2, $4, $[[T0]] -+ -+ %r = ashr i8 %a, %b -+ ret i8 %r -+} -+ -+define signext i16 @ashr_i16(i16 signext %a, i16 signext %b) { -+entry: -+; ALL-LABEL: ashr_i16: -+ -+ ; FIXME: The andi instruction is redundant. -+ ; ALL: andi $[[T0:[0-9]+]], $5, 65535 -+ ; ALL: srav $2, $4, $[[T0]] -+ -+ %r = ashr i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @ashr_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: ashr_i32: -+ -+ ; ALL: srav $2, $4, $5 -+ -+ %r = ashr i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @ashr_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: ashr_i64: -+ -+ ; M2: srav $[[T0:[0-9]+]], $4, $7 -+ ; M2: andi $[[T1:[0-9]+]], $7, 32 -+ ; M2: bnez $[[T1]], $[[BB0:BB[0-9_]+]] -+ ; M2: move $3, $[[T0]] -+ ; M2: srlv $[[T2:[0-9]+]], $5, $7 -+ ; M2: not $[[T3:[0-9]+]], $7 -+ ; M2: sll $[[T4:[0-9]+]], $4, 1 -+ ; M2: sllv $[[T5:[0-9]+]], $[[T4]], $[[T3]] -+ ; M2: or $3, $[[T3]], $[[T2]] -+ ; M2: $[[BB0]]: -+ ; M2: beqz $[[T1]], $[[BB1:BB[0-9_]+]] -+ ; M2: nop -+ ; M2: sra $2, $4, 31 -+ ; M2: $[[BB1]]: -+ ; M2: jr $ra -+ ; M2: nop -+ -+ ; 32R1-R2: srlv $[[T0:[0-9]+]], $5, $7 -+ ; 32R1-R2: not $[[T1:[0-9]+]], $7 -+ ; 32R1-R2: sll $[[T2:[0-9]+]], $4, 1 -+ ; 32R1-R2: sllv $[[T3:[0-9]+]], $[[T2]], $[[T1]] -+ ; 32R1-R2: or $3, $[[T3]], $[[T0]] -+ ; 32R1-R2: srav $[[T4:[0-9]+]], $4, $7 -+ ; 32R1-R2: andi $[[T5:[0-9]+]], $7, 32 -+ ; 32R1-R2: movn $3, $[[T4]], $[[T5]] -+ ; 32R1-R2: sra $4, $4, 31 -+ ; 32R1-R2: jr $ra -+ ; 32R1-R2: movn $2, $4, $[[T5]] -+ -+ ; 32R6: srav $[[T0:[0-9]+]], $4, $7 -+ ; 32R6: andi $[[T1:[0-9]+]], $7, 32 -+ ; 32R6: seleqz $[[T2:[0-9]+]], $[[T0]], $[[T1]] -+ ; 32R6: sra $[[T3:[0-9]+]], $4, 31 -+ ; 32R6: selnez $[[T4:[0-9]+]], $[[T3]], $[[T1]] -+ ; 32R6: or $[[T5:[0-9]+]], $[[T4]], $[[T2]] -+ ; 32R6: srlv $[[T6:[0-9]+]], $5, $7 -+ ; 32R6: not $[[T7:[0-9]+]], $7 -+ ; 32R6: sll $[[T8:[0-9]+]], $4, 1 -+ ; 32R6: sllv $[[T9:[0-9]+]], $[[T8]], $[[T7]] -+ ; 32R6: or $[[T10:[0-9]+]], $[[T9]], $[[T6]] -+ ; 32R6: seleqz $[[T11:[0-9]+]], $[[T10]], $[[T1]] -+ ; 32R6: selnez $[[T12:[0-9]+]], $[[T0]], $[[T1]] -+ ; 32R6: jr $ra -+ ; 32R6: or $3, $[[T0]], $[[T11]] -+ -+ ; FIXME: The sll instruction below is redundant. -+ ; GP64: sll $[[T0:[0-9]+]], $5, 0 -+ ; GP64: dsrav $2, $4, $[[T0]] -+ -+ %r = ashr i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @ashr_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: ashr_i128: -+ -+ ; GP32: lw $25, %call16(__ashrti3)($gp) -+ -+ ; M3: sll $[[T0:[0-9]+]], $7, 0 -+ ; M3: dsrav $[[T1:[0-9]+]], $4, $[[T0]] -+ ; M3: andi $[[T2:[0-9]+]], $[[T0]], 32 -+ ; M3: bnez $[[T3:[0-9]+]], $[[BB0:BB[0-9_]+]] -+ ; M3: move $3, $[[T1]] -+ ; M3: dsrlv $[[T4:[0-9]+]], $5, $[[T0]] -+ ; M3: dsll $[[T5:[0-9]+]], $4, 1 -+ ; M3: not $[[T6:[0-9]+]], $[[T0]] -+ ; M3: dsllv $[[T7:[0-9]+]], $[[T5]], $[[T6]] -+ ; M3: or $3, $[[T7]], $[[T4]] -+ ; M3: $[[BB0]]: -+ ; M3: beqz $[[T3]], $[[BB1:BB[0-9_]+]] -+ ; M3: nop -+ ; M3: dsra $2, $4, 31 -+ ; M3: $[[BB1]]: -+ ; M3: jr $ra -+ ; M3: nop -+ -+ ; GP64-NOT-R6: sll $[[T0:[0-9]+]], $7, 0 -+ ; GP64-NOT-R6: dsrlv $[[T1:[0-9]+]], $5, $[[T0]] -+ ; GP64-NOT-R6: dsll $[[T2:[0-9]+]], $4, 1 -+ ; GP64-NOT-R6: not $[[T3:[0-9]+]], $[[T0]] -+ ; GP64-NOT-R6: dsllv $[[T4:[0-9]+]], $[[T2]], $[[T3]] -+ ; GP64-NOT-R6: or $3, $[[T4]], $[[T1]] -+ ; GP64-NOT-R6: dsrav $2, $4, $[[T0]] -+ ; GP64-NOT-R6: andi $[[T5:[0-9]+]], $[[T0]], 32 -+ -+ ; GP64-NOT-R6: movn $3, $2, $[[T5]] -+ ; GP64-NOT-R6: dsra $[[T6:[0-9]+]], $4, 31 -+ ; GP64-NOT-R6: jr $ra -+ ; GP64-NOT-R6: movn $2, $[[T6]], $[[T5]] -+ -+ ; 64R6: sll $[[T0:[0-9]+]], $7, 0 -+ ; 64R6: dsrav $[[T1:[0-9]+]], $4, $[[T0]] -+ ; 64R6: andi $[[T2:[0-9]+]], $[[T0]], 32 -+ ; 64R6: sll $[[T3:[0-9]+]], $[[T2]], 0 -+ ; 64R6: seleqz $[[T4:[0-9]+]], $[[T1]], $[[T3]] -+ ; 64R6: dsra $[[T5:[0-9]+]], $4, 31 -+ ; 64R6: selnez $[[T6:[0-9]+]], $[[T5]], $[[T3]] -+ ; 64R6: or $2, $[[T6]], $[[T4]] -+ ; 64R6: dsrlv $[[T7:[0-9]+]], $5, $[[T0]] -+ ; 64R6: dsll $[[T8:[0-9]+]], $4, 1 -+ ; 64R6: not $[[T9:[0-9]+]], $[[T0]] -+ ; 64R6: dsllv $[[T10:[0-9]+]], $[[T8]], $[[T9]] -+ ; 64R6: or $[[T11:[0-9]+]], $[[T10]], $[[T7]] -+ ; 64R6: seleqz $[[T12:[0-9]+]], $[[T11]], $[[T3]] -+ ; 64R6: selnez $[[T13:[0-9]+]], $[[T1]], $[[T3]] -+ ; 64R6: jr $ra -+ ; 64R6: or $3, $[[T13]], $[[T12]] -+ -+ %r = ashr i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/lshr.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/lshr.ll -+++ test/CodeGen/Mips/llvm-ir/lshr.ll -@@ -0,0 +1,176 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 \ -+; RUN: -check-prefix=M2 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -check-prefix=NOT-R2-R6 \ -+; RUN: -check-prefix=32R1-R2 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 \ -+; RUN: -check-prefix=32R1-R2 -check-prefix=R2-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 \ -+; RUN: -check-prefix=32R6 -check-prefix=R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=M3 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=64R6 -check-prefix=R2-R6 -+ -+define signext i1 @lshr_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: lshr_i1: -+ -+ ; ALL: move $2, $4 -+ -+ %r = lshr i1 %a, %b -+ ret i1 %r -+} -+ -+define zeroext i8 @lshr_i8(i8 zeroext %a, i8 zeroext %b) { -+entry: -+; ALL-LABEL: lshr_i8: -+ -+ ; ALL: srlv $[[T0:[0-9]+]], $4, $5 -+ ; ALL: andi $2, $[[T0]], 255 -+ -+ %r = lshr i8 %a, %b -+ ret i8 %r -+} -+ -+define zeroext i16 @lshr_i16(i16 zeroext %a, i16 zeroext %b) { -+entry: -+; ALL-LABEL: lshr_i16: -+ -+ ; ALL: srlv $[[T0:[0-9]+]], $4, $5 -+ ; ALL: andi $2, $[[T0]], 65535 -+ -+ %r = lshr i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @lshr_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: lshr_i32: -+ -+ ; ALL: srlv $2, $4, $5 -+ -+ %r = lshr i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @lshr_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: lshr_i64: -+ -+ ; M2: srlv $[[T0:[0-9]+]], $4, $7 -+ ; M2: andi $[[T1:[0-9]+]], $7, 32 -+ ; M2: bnez $[[T1]], $[[BB0:BB[0-9_]+]] -+ ; M2: move $3, $[[T0]] -+ ; M2: srlv $[[T2:[0-9]+]], $5, $7 -+ ; M2: not $[[T3:[0-9]+]], $7 -+ ; M2: sll $[[T4:[0-9]+]], $4, 1 -+ ; M2: sllv $[[T5:[0-9]+]], $[[T4]], $[[T3]] -+ ; M2: or $3, $[[T3]], $[[T2]] -+ ; M2: $[[BB0]]: -+ ; M2: bnez $[[T1]], $[[BB1:BB[0-9_]+]] -+ ; M2: addiu $2, $zero, 0 -+ ; M2: move $2, $[[T0]] -+ ; M2: $[[BB1]]: -+ ; M2: jr $ra -+ ; M2: nop -+ -+ ; 32R1-R2: srlv $[[T0:[0-9]+]], $5, $7 -+ ; 32R1-R2: not $[[T1:[0-9]+]], $7 -+ ; 32R1-R2: sll $[[T2:[0-9]+]], $4, 1 -+ ; 32R1-R2: sllv $[[T3:[0-9]+]], $[[T2]], $[[T1]] -+ ; 32R1-R2: or $3, $[[T3]], $[[T0]] -+ ; 32R1-R2: srlv $[[T4:[0-9]+]], $4, $7 -+ ; 32R1-R2: andi $[[T5:[0-9]+]], $7, 32 -+ ; 32R1-R2: movn $3, $[[T4]], $[[T5]] -+ ; 32R1-R2: jr $ra -+ ; 32R1-R2: movn $2, $zero, $[[T5]] -+ -+ ; 32R6: srlv $[[T0:[0-9]+]], $5, $7 -+ ; 32R6: not $[[T1:[0-9]+]], $7 -+ ; 32R6: sll $[[T2:[0-9]+]], $4, 1 -+ ; 32R6: sllv $[[T3:[0-9]+]], $[[T2]], $[[T1]] -+ ; 32R6: or $[[T4:[0-9]+]], $[[T3]], $[[T0]] -+ ; 32R6: andi $[[T5:[0-9]+]], $7, 32 -+ ; 32R6: seleqz $[[T6:[0-9]+]], $[[T4]], $[[T3]] -+ ; 32R6: srlv $[[T7:[0-9]+]], $4, $7 -+ ; 32R6: selnez $[[T8:[0-9]+]], $[[T7]], $[[T5]] -+ ; 32R6: or $3, $[[T8]], $[[T6]] -+ ; 32R6: jr $ra -+ ; 32R6: seleqz $2, $[[T7]], $[[T5]] -+ -+ ; GP64: sll $[[T0:[0-9]+]], $5, 0 -+ ; GP64: dsrlv $2, $4, $[[T0]] -+ -+ %r = lshr i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @lshr_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: lshr_i128: -+ -+ ; GP32: lw $25, %call16(__lshrti3)($gp) -+ -+ ; M3: sll $[[T0:[0-9]+]], $7, 0 -+ ; M3: dsrlv $[[T1:[0-9]+]], $4, $[[T0]] -+ ; M3: andi $[[T2:[0-9]+]], $[[T0]], 32 -+ ; M3: bnez $[[T3:[0-9]+]], $[[BB0:BB[0-9_]+]] -+ ; M3: move $3, $[[T1]] -+ ; M3: dsrlv $[[T4:[0-9]+]], $5, $[[T0]] -+ ; M3: dsll $[[T5:[0-9]+]], $4, 1 -+ ; M3: not $[[T6:[0-9]+]], $[[T0]] -+ ; M3: dsllv $[[T7:[0-9]+]], $[[T5]], $[[T6]] -+ ; M3: or $3, $[[T7]], $[[T4]] -+ ; M3: $[[BB0]]: -+ ; M3: bnez $[[T3]], $[[BB1:BB[0-9_]+]] -+ ; M3: daddiu $2, $zero, 0 -+ ; M3: move $2, $[[T1]] -+ ; M3: $[[BB1]]: -+ ; M3: jr $ra -+ ; M3: nop -+ -+ ; GP64-NOT-R6: sll $[[T0:[0-9]+]], $7, 0 -+ ; GP64-NOT-R6: dsrlv $[[T1:[0-9]+]], $5, $[[T0]] -+ ; GP64-NOT-R6: dsll $[[T2:[0-9]+]], $4, 1 -+ ; GP64-NOT-R6: not $[[T3:[0-9]+]], $[[T0]] -+ ; GP64-NOT-R6: dsllv $[[T4:[0-9]+]], $[[T2]], $[[T3]] -+ ; GP64-NOT-R6: or $3, $[[T4]], $[[T1]] -+ ; GP64-NOT-R6: dsrlv $2, $4, $[[T0]] -+ ; GP64-NOT-R6: andi $[[T5:[0-9]+]], $[[T0]], 32 -+ ; GP64-NOT-R6: movn $3, $2, $[[T5]] -+ ; GP64-NOT-R6: jr $ra -+ ; GP64-NOT-R6: movn $2, $zero, $1 -+ -+ ; 64R6: sll $[[T0:[0-9]+]], $7, 0 -+ ; 64R6: dsrlv $[[T1:[0-9]+]], $5, $[[T0]] -+ ; 64R6: dsll $[[T2:[0-9]+]], $4, 1 -+ ; 64R6: not $[[T3:[0-9]+]], $[[T0]] -+ ; 64R6: dsllv $[[T4:[0-9]+]], $[[T2]], $[[T3]] -+ ; 64R6: or $[[T5:[0-9]+]], $[[T4]], $[[T1]] -+ ; 64R6: andi $[[T6:[0-9]+]], $[[T0]], 32 -+ ; 64R6: sll $[[T7:[0-9]+]], $[[T6]], 0 -+ ; 64R6: seleqz $[[T8:[0-9]+]], $[[T5]], $[[T7]] -+ ; 64R6: dsrlv $[[T9:[0-9]+]], $4, $[[T0]] -+ ; 64R6: selnez $[[T10:[0-9]+]], $[[T9]], $[[T7]] -+ ; 64R6: or $3, $[[T10]], $[[T8]] -+ ; 64R6: jr $ra -+ ; 64R6: seleqz $2, $[[T0]], $[[T7]] -+ -+ %r = lshr i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/mul.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/mul.ll -+++ test/CodeGen/Mips/llvm-ir/mul.ll -@@ -1,19 +1,19 @@ --; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ --; RUN: -check-prefix=ALL -check-prefix=M2 --; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ --; RUN: -check-prefix=ALL -check-prefix=32R1-R2 -check-prefix=32R1 --; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ --; RUN: -check-prefix=ALL -check-prefix=32R1-R2 -check-prefix=32R2 --; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ --; RUN: -check-prefix=ALL -check-prefix=32R6 --; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ --; RUN: -check-prefix=ALL -check-prefix=M4 --; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ --; RUN: -check-prefix=ALL -check-prefix=64R1-R2 --; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ --; RUN: -check-prefix=ALL -check-prefix=64R1-R2 --; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ --; RUN: -check-prefix=ALL -check-prefix=64R6 -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s -check-prefix=ALL \ -+; RUN: -check-prefix=M2 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s -check-prefix=ALL \ -+; RUN: -check-prefix=32R1-R2 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s -check-prefix=ALL \ -+; RUN: -check-prefix=32R1-R2 -check-prefix=32R2 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s -check-prefix=ALL \ -+; RUN: -check-prefix=32R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s -check-prefix=ALL \ -+; RUN: -check-prefix=M4 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s -check-prefix=ALL \ -+; RUN: -check-prefix=64R1-R2 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s -check-prefix=ALL \ -+; RUN: -check-prefix=64R1-R2 -check-prefix=GP64 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s -check-prefix=ALL \ -+; RUN: -check-prefix=64R6 - - define signext i1 @mul_i1(i1 signext %a, i1 signext %b) { - entry: -@@ -179,3 +179,30 @@ entry: - %r = mul i64 %a, %b - ret i64 %r - } -+ -+define signext i128 @mul_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: mul_i128: -+ -+ ; GP32: lw $25, %call16(__multi3)($gp) -+ -+ ; GP64-NOT-R6: dmult $4, $7 -+ ; GP64-NOT-R6: mflo $[[T0:[0-9]+]] -+ ; GP64-NOT-R6: dmult $5, $6 -+ ; GP64-NOT-R6: mflo $[[T1:[0-9]+]] -+ ; GP64-NOT-R6: dmultu $5, $7 -+ ; GP64-NOT-R6: mflo $3 -+ ; GP64-NOT-R6: mfhi $[[T2:[0-9]+]] -+ ; GP64-NOT-R6: daddu $[[T3:[0-9]+]], $[[T2]], $[[T1]] -+ ; GP64-NOT-R6: daddu $2, $[[T3:[0-9]+]], $[[T0]] -+ -+ ; 64R6: dmul $[[T0:[0-9]+]], $5, $6 -+ ; 64R6: dmuhu $[[T1:[0-9]+]], $5, $7 -+ ; 64R6: daddu $[[T2:[0-9]+]], $[[T1]], $[[T0]] -+ ; 64R6: dmul $[[T3:[0-9]+]], $4, $7 -+ ; 64R6: daddu $2, $[[T2]], $[[T3]] -+ ; 64R6: dmul $3, $5, $7 -+ -+ %r = mul i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/or.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/or.ll -+++ test/CodeGen/Mips/llvm-ir/or.ll -@@ -0,0 +1,95 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+ -+define signext i1 @or_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: or_i1: -+ -+ ; ALL: or $2, $4, $5 -+ -+ %r = or i1 %a, %b -+ ret i1 %r -+} -+ -+define signext i8 @or_i8(i8 signext %a, i8 signext %b) { -+entry: -+; ALL-LABEL: or_i8: -+ -+ ; ALL: or $2, $4, $5 -+ -+ %r = or i8 %a, %b -+ ret i8 %r -+} -+ -+define signext i16 @or_i16(i16 signext %a, i16 signext %b) { -+entry: -+; ALL-LABEL: or_i16: -+ -+ ; ALL: or $2, $4, $5 -+ -+ %r = or i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @or_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: or_i32: -+ -+ ; GP32: or $2, $4, $5 -+ -+ ; GP64: or $[[T0:[0-9]+]], $4, $5 -+ ; FIXME: The sll instruction below is redundant. -+ ; GP64: sll $2, $[[T0]], 0 -+ -+ %r = or i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @or_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: or_i64: -+ -+ ; GP32: or $2, $4, $6 -+ ; GP32: or $3, $5, $7 -+ -+ ; GP64: or $2, $4, $5 -+ -+ %r = or i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @or_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: or_i128: -+ -+ ; GP32: lw $[[T0:[0-9]+]], 24($sp) -+ ; GP32: lw $[[T1:[0-9]+]], 20($sp) -+ ; GP32: lw $[[T2:[0-9]+]], 16($sp) -+ ; GP32: or $2, $4, $[[T2]] -+ ; GP32: or $3, $5, $[[T1]] -+ ; GP32: or $4, $6, $[[T0]] -+ ; GP32: lw $[[T3:[0-9]+]], 28($sp) -+ ; GP32: or $5, $7, $[[T3]] -+ -+ ; GP64: or $2, $4, $6 -+ ; GP64: or $3, $5, $7 -+ -+ %r = or i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/sdiv.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/sdiv.ll -+++ test/CodeGen/Mips/llvm-ir/sdiv.ll -@@ -0,0 +1,136 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=R2 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=R2 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=R6 -check-prefix=64R6 -+ -+define signext i1 @sdiv_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: sdiv_i1: -+ -+ ; NOT-R6: div $zero, $4, $5 -+ ; NOT-R6: teq $5, $zero, 7 -+ ; NOT-R6: mflo $[[T0:[0-9]+]] -+ ; FIXME: The sll/sra instructions are redundant since div is signed. -+ ; NOT-R6: sll $[[T1:[0-9]+]], $[[T0]], 31 -+ ; NOT-R6: sra $2, $[[T1]], 31 -+ -+ ; R6: div $[[T0:[0-9]+]], $4, $5 -+ ; R6: teq $5, $zero, 7 -+ ; FIXME: The sll/sra instructions are redundant since div is signed. -+ ; R6: sll $[[T1:[0-9]+]], $[[T0]], 31 -+ ; R6: sra $2, $[[T1]], 31 -+ -+ %r = sdiv i1 %a, %b -+ ret i1 %r -+} -+ -+define signext i8 @sdiv_i8(i8 signext %a, i8 signext %b) { -+entry: -+; ALL-LABEL: sdiv_i8: -+ -+ ; NOT-R2-R6: div $zero, $4, $5 -+ ; NOT-R2-R6: teq $5, $zero, 7 -+ ; NOT-R2-R6: mflo $[[T0:[0-9]+]] -+ ; FIXME: The sll/sra instructions are redundant since div is signed. -+ ; NOT-R2-R6: sll $[[T1:[0-9]+]], $[[T0]], 24 -+ ; NOT-R2-R6: sra $2, $[[T1]], 24 -+ -+ ; R2: div $zero, $4, $5 -+ ; R2: teq $5, $zero, 7 -+ ; R2: mflo $[[T0:[0-9]+]] -+ ; FIXME: This instruction is redundant. -+ ; R2: seb $2, $[[T0]] -+ -+ ; R6: div $[[T0:[0-9]+]], $4, $5 -+ ; R6: teq $5, $zero, 7 -+ ; FIXME: This instruction is redundant. -+ ; R6: seb $2, $[[T0]] -+ -+ %r = sdiv i8 %a, %b -+ ret i8 %r -+} -+ -+define signext i16 @sdiv_i16(i16 signext %a, i16 signext %b) { -+entry: -+; ALL-LABEL: sdiv_i16: -+ -+ ; NOT-R2-R6: div $zero, $4, $5 -+ ; NOT-R2-R6: teq $5, $zero, 7 -+ ; NOT-R2-R6: mflo $[[T0:[0-9]+]] -+ ; FIXME: The sll/sra instructions are redundant since div is signed. -+ ; NOT-R2-R6: sll $[[T1:[0-9]+]], $[[T0]], 16 -+ ; NOT-R2-R6: sra $2, $[[T1]], 16 -+ -+ ; R2: div $zero, $4, $5 -+ ; R2: teq $5, $zero, 7 -+ ; R2: mflo $[[T0:[0-9]+]] -+ ; FIXME: This is instruction is redundant since div is signed. -+ ; R2: seh $2, $[[T0]] -+ -+ ; R6: div $[[T0:[0-9]+]], $4, $5 -+ ; R6: teq $5, $zero, 7 -+ ; FIXME: This is instruction is redundant since div is signed. -+ ; R6: seh $2, $[[T0]] -+ -+ %r = sdiv i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @sdiv_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: sdiv_i32: -+ -+ ; NOT-R6: div $zero, $4, $5 -+ ; NOT-R6: teq $5, $zero, 7 -+ ; NOT-R6: mflo $2 -+ -+ ; R6: div $2, $4, $5 -+ ; R6: teq $5, $zero, 7 -+ -+ %r = sdiv i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @sdiv_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: sdiv_i64: -+ -+ ; GP32: lw $25, %call16(__divdi3)($gp) -+ -+ ; GP64-NOT-R6: ddiv $zero, $4, $5 -+ ; GP64-NOT-R6: teq $5, $zero, 7 -+ ; GP64-NOT-R6: mflo $2 -+ -+ ; 64R6: ddiv $2, $4, $5 -+ ; 64R6: teq $5, $zero, 7 -+ -+ %r = sdiv i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @sdiv_i128(i128 signext %a, i128 signext %b) { -+entry: -+ ; ALL-LABEL: sdiv_i128: -+ -+ ; GP32: lw $25, %call16(__divti3)($gp) -+ -+ ; GP64-NOT-R6: ld $25, %call16(__divti3)($gp) -+ ; 64R6: ld $25, %call16(__divti3)($gp) -+ -+ %r = sdiv i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/shl.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/shl.ll -+++ test/CodeGen/Mips/llvm-ir/shl.ll -@@ -0,0 +1,188 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 \ -+; RUN: -check-prefix=M2 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -check-prefix=NOT-R2-R6 \ -+; RUN: -check-prefix=32R1-R2 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 \ -+; RUN: -check-prefix=32R1-R2 -check-prefix=R2-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 \ -+; RUN: -check-prefix=32R6 -check-prefix=R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=M3 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 \ -+; RUN: -check-prefix=64R6 -check-prefix=R2-R6 -+ -+define signext i1 @shl_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: shl_i1: -+ -+ ; ALL: move $2, $4 -+ -+ %r = shl i1 %a, %b -+ ret i1 %r -+} -+ -+define signext i8 @shl_i8(i8 signext %a, i8 signext %b) { -+entry: -+; ALL-LABEL: shl_i8: -+ -+ ; NOT-R2-R6: andi $[[T0:[0-9]+]], $5, 255 -+ ; NOT-R2-R6: sllv $[[T1:[0-9]+]], $4, $[[T0]] -+ ; NOT-R2-R6: sll $[[T2:[0-9]+]], $[[T1]], 24 -+ ; NOT-R2-R6: sra $2, $[[T2]], 24 -+ -+ ; R2-R6: andi $[[T0:[0-9]+]], $5, 255 -+ ; R2-R6: sllv $[[T1:[0-9]+]], $4, $[[T0]] -+ ; R2-R6: seb $2, $[[T1]] -+ -+ %r = shl i8 %a, %b -+ ret i8 %r -+} -+ -+define signext i16 @shl_i16(i16 signext %a, i16 signext %b) { -+entry: -+; ALL-LABEL: shl_i16: -+ -+ ; NOT-R2-R6: andi $[[T0:[0-9]+]], $5, 65535 -+ ; NOT-R2-R6: sllv $[[T1:[0-9]+]], $4, $[[T0]] -+ ; NOT-R2-R6: sll $[[T2:[0-9]+]], $[[T1]], 16 -+ ; NOT-R2-R6: sra $2, $[[T2]], 16 -+ -+ ; R2-R6: andi $[[T0:[0-9]+]], $5, 65535 -+ ; R2-R6: sllv $[[T1:[0-9]+]], $4, $[[T0]] -+ ; R2-R6: seh $2, $[[T1]] -+ -+ %r = shl i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @shl_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: shl_i32: -+ -+ ; ALL: sllv $2, $4, $5 -+ -+ %r = shl i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @shl_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: shl_i64: -+ -+ ; M2: sllv $[[T0:[0-9]+]], $5, $7 -+ ; M2: andi $[[T1:[0-9]+]], $7, 32 -+ ; M2: bnez $[[T1]], $[[BB0:BB[0-9_]+]] -+ ; M2: move $2, $[[T0]] -+ ; M2: sllv $[[T2:[0-9]+]], $4, $7 -+ ; M2: not $[[T3:[0-9]+]], $7 -+ ; M2: srl $[[T4:[0-9]+]], $5, 1 -+ ; M2: srlv $[[T5:[0-9]+]], $[[T4]], $[[T3]] -+ ; M2: or $2, $[[T2]], $[[T3]] -+ ; M2: $[[BB0]]: -+ ; M2: bnez $[[T1]], $[[BB1:BB[0-9_]+]] -+ ; M2: addiu $3, $zero, 0 -+ ; M2: move $3, $[[T0]] -+ ; M2: $[[BB1]]: -+ ; M2: jr $ra -+ ; M2: nop -+ -+ ; 32R1-R2: sllv $[[T0:[0-9]+]], $4, $7 -+ ; 32R1-R2: not $[[T1:[0-9]+]], $7 -+ ; 32R1-R2: srl $[[T2:[0-9]+]], $5, 1 -+ ; 32R1-R2: srlv $[[T3:[0-9]+]], $[[T2]], $[[T1]] -+ ; 32R1-R2: or $2, $[[T0]], $[[T3]] -+ ; 32R1-R2: sllv $[[T4:[0-9]+]], $5, $7 -+ ; 32R1-R2: andi $[[T5:[0-9]+]], $7, 32 -+ ; 32R1-R2: movn $2, $[[T4]], $[[T5]] -+ ; 32R1-R2: jr $ra -+ ; 32R1-R2: movn $3, $zero, $[[T5]] -+ -+ ; 32R6: sllv $[[T0:[0-9]+]], $4, $7 -+ ; 32R6: not $[[T1:[0-9]+]], $7 -+ ; 32R6: srl $[[T2:[0-9]+]], $5, 1 -+ ; 32R6: srlv $[[T3:[0-9]+]], $[[T2]], $[[T1]] -+ ; 32R6: or $[[T4:[0-9]+]], $[[T0]], $[[T3]] -+ ; 32R6: andi $[[T5:[0-9]+]], $7, 32 -+ ; 32R6: seleqz $[[T6:[0-9]+]], $[[T4]], $[[T2]] -+ ; 32R6: sllv $[[T7:[0-9]+]], $5, $7 -+ ; 32R6: selnez $[[T8:[0-9]+]], $[[T7]], $[[T5]] -+ ; 32R6: or $2, $[[T8]], $[[T6]] -+ ; 32R6: jr $ra -+ ; 32R6: seleqz $3, $[[T7]], $[[T5]] -+ -+ ; GP64: sll $[[T0:[0-9]+]], $5, 0 -+ ; GP64: dsllv $2, $4, $1 -+ -+ %r = shl i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @shl_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: shl_i128: -+ -+ ; GP32: lw $25, %call16(__ashlti3)($gp) -+ -+ ; M3: sll $[[T0:[0-9]+]], $7, 0 -+ ; M3: dsllv $[[T1:[0-9]+]], $5, $[[T0]] -+ ; M3: andi $[[T2:[0-9]+]], $[[T0]], 32 -+ ; M3: bnez $[[T3:[0-9]+]], $[[BB0:BB[0-9_]+]] -+ ; M3: move $2, $[[T1]] -+ ; M3: dsllv $[[T4:[0-9]+]], $4, $[[T0]] -+ ; M3: dsrl $[[T5:[0-9]+]], $5, 1 -+ ; M3: not $[[T6:[0-9]+]], $[[T0]] -+ ; M3: dsrlv $[[T7:[0-9]+]], $[[T5]], $[[T6]] -+ ; M3: or $2, $[[T4]], $[[T7]] -+ ; M3: $[[BB0]]: -+ ; M3: bnez $[[T3]], $[[BB1:BB[0-9_]+]] -+ ; M3: daddiu $3, $zero, 0 -+ ; M3: move $3, $[[T1]] -+ ; M3: $[[BB1]]: -+ ; M3: jr $ra -+ ; M3: nop -+ -+ ; GP64-NOT-R6: sll $[[T0:[0-9]+]], $7, 0 -+ ; GP64-NOT-R6: dsllv $[[T1:[0-9]+]], $4, $[[T0]] -+ ; GP64-NOT-R6: dsrl $[[T2:[0-9]+]], $5, 1 -+ ; GP64-NOT-R6: not $[[T3:[0-9]+]], $[[T0]] -+ ; GP64-NOT-R6: dsrlv $[[T4:[0-9]+]], $[[T2]], $[[T3]] -+ ; GP64-NOT-R6: or $2, $[[T1]], $[[T4]] -+ ; GP64-NOT-R6: dsllv $3, $5, $[[T0]] -+ ; GP64-NOT-R6: andi $[[T5:[0-9]+]], $[[T0]], 32 -+ ; GP64-NOT-R6: movn $2, $3, $[[T5]] -+ ; GP64-NOT-R6: jr $ra -+ ; GP64-NOT-R6: movn $3, $zero, $1 -+ -+ ; 64R6: sll $[[T0:[0-9]+]], $7, 0 -+ ; 64R6: dsllv $[[T1:[0-9]+]], $4, $[[T0]] -+ ; 64R6: dsrl $[[T2:[0-9]+]], $5, 1 -+ ; 64R6: not $[[T3:[0-9]+]], $[[T0]] -+ ; 64R6: dsrlv $[[T4:[0-9]+]], $[[T2]], $[[T3]] -+ ; 64R6: or $[[T5:[0-9]+]], $[[T1]], $[[T4]] -+ ; 64R6: andi $[[T6:[0-9]+]], $[[T0]], 32 -+ ; 64R6: sll $[[T7:[0-9]+]], $[[T6]], 0 -+ ; 64R6: seleqz $[[T8:[0-9]+]], $[[T5]], $[[T7]] -+ ; 64R6: dsllv $[[T9:[0-9]+]], $5, $[[T0]] -+ ; 64R6: selnez $[[T10:[0-9]+]], $[[T9]], $[[T7]] -+ ; 64R6: or $2, $[[T10]], $[[T8]] -+ ; 64R6: jr $ra -+ ; 64R6: seleqz $3, $[[T0]], $[[T7]] -+ -+ %r = shl i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/srem.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/srem.ll -+++ test/CodeGen/Mips/llvm-ir/srem.ll -@@ -0,0 +1,129 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=GP32 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=GP32 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s -check-prefix=GP32 \ -+; RUN: -check-prefix=R2 -check-prefix=R2-R6 -check-prefix=NOT-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=GP32 -check-prefix=R6 -check-prefix=R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=R2 -check-prefix=R2-R6 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=64R6 -check-prefix=R6 -check-prefix=R2-R6 -+ -+define signext i1 @srem_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: srem_i1: -+ -+ ; NOT-R6: div $zero, $4, $5 -+ ; NOT-R6: teq $5, $zero, 7 -+ ; NOT-R6: mfhi $[[T0:[0-9]+]] -+ ; NOT-R6: sll $[[T1:[0-9]+]], $[[T0]], 31 -+ ; NOT-R6: sra $2, $[[T1]], 31 -+ -+ ; R6: mod $[[T0:[0-9]+]], $4, $5 -+ ; R6: teq $5, $zero, 7 -+ ; R6: sll $[[T3:[0-9]+]], $[[T0]], 31 -+ ; R6: sra $2, $[[T3]], 31 -+ -+ %r = srem i1 %a, %b -+ ret i1 %r -+} -+ -+define signext i8 @srem_i8(i8 signext %a, i8 signext %b) { -+entry: -+; ALL-LABEL: srem_i8: -+ -+ ; NOT-R2-R6: div $zero, $4, $5 -+ ; NOT-R2-R6: teq $5, $zero, 7 -+ ; NOT-R2-R6: mfhi $[[T0:[0-9]+]] -+ ; NOT-R2-R6: sll $[[T1:[0-9]+]], $[[T0]], 24 -+ ; NOT-R2-R6: sra $2, $[[T1]], 24 -+ -+ ; R2: div $zero, $4, $5 -+ ; R2: teq $5, $zero, 7 -+ ; R2: mfhi $[[T0:[0-9]+]] -+ ; R2: seb $2, $[[T0]] -+ -+ ; R6: mod $[[T0:[0-9]+]], $4, $5 -+ ; R6: teq $5, $zero, 7 -+ ; R6: seb $2, $[[T0]] -+ -+ %r = srem i8 %a, %b -+ ret i8 %r -+} -+ -+define signext i16 @srem_i16(i16 signext %a, i16 signext %b) { -+entry: -+; ALL-LABEL: srem_i16: -+ -+ ; NOT-R2-R6: div $zero, $4, $5 -+ ; NOT-R2-R6: teq $5, $zero, 7 -+ ; NOT-R2-R6: mfhi $[[T0:[0-9]+]] -+ ; NOT-R2-R6: sll $[[T1:[0-9]+]], $[[T0]], 16 -+ ; NOT-R2-R6: sra $2, $[[T1]], 16 -+ -+ ; R2: div $zero, $4, $5 -+ ; R2: teq $5, $zero, 7 -+ ; R2: mfhi $[[T0:[0-9]+]] -+ ; R2: seh $2, $[[T1]] -+ -+ ; R6: mod $[[T0:[0-9]+]], $4, $5 -+ ; R6: teq $5, $zero, 7 -+ ; R6: seh $2, $[[T0]] -+ -+ %r = srem i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @srem_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: srem_i32: -+ -+ ; NOT-R6: div $zero, $4, $5 -+ ; NOT-R6: teq $5, $zero, 7 -+ ; NOT-R6: mfhi $2 -+ -+ ; R6: mod $2, $4, $5 -+ ; R6: teq $5, $zero, 7 -+ -+ %r = srem i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @srem_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: srem_i64: -+ -+ ; GP32: lw $25, %call16(__moddi3)($gp) -+ -+ ; GP64-NOT-R6: ddiv $zero, $4, $5 -+ ; GP64-NOT-R6: teq $5, $zero, 7 -+ ; GP64-NOT-R6: mfhi $2 -+ -+ ; 64R6: dmod $2, $4, $5 -+ ; 64R6: teq $5, $zero, 7 -+ -+ %r = srem i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @srem_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: srem_i128: -+ -+ ; GP32: lw $25, %call16(__modti3)($gp) -+ -+ ; GP64-NOT-R6: ld $25, %call16(__modti3)($gp) -+ ; 64-R6: ld $25, %call16(__modti3)($gp) -+ -+ %r = srem i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/sub.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/sub.ll -+++ test/CodeGen/Mips/llvm-ir/sub.ll -@@ -0,0 +1,114 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=NOT-R2-R6 -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=R2-R6 -check-prefix=GP64 -+ -+define signext i1 @sub_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: sub_i1: -+ -+ ; ALL: subu $[[T0:[0-9]+]], $4, $5 -+ ; ALL: sll $[[T0]], $[[T0]], 31 -+ ; ALL: sra $2, $[[T0]], 31 -+ -+ %r = sub i1 %a, %b -+ ret i1 %r -+} -+ -+define signext i8 @sub_i8(i8 signext %a, i8 signext %b) { -+entry: -+; ALL-LABEL: sub_i8: -+ -+ ; NOT-R2-R6: subu $[[T0:[0-9]+]], $4, $5 -+ ; NOT-R2-R6: sll $[[T0]], $[[T0]], 24 -+ ; NOT-R2-R6: sra $2, $[[T0]], 24 -+ -+ ; R2-R6: subu $[[T0:[0-9]+]], $4, $5 -+ ; R2-R6: seb $2, $[[T0:[0-9]+]] -+ -+ %r = sub i8 %a, %b -+ ret i8 %r -+} -+ -+define signext i16 @sub_i16(i16 signext %a, i16 signext %b) { -+entry: -+; ALL-LABEL: sub_i16: -+ -+ ; NOT-R2-R6: subu $[[T0:[0-9]+]], $4, $5 -+ ; NOT-R2-R6: sll $[[T0]], $[[T0]], 16 -+ ; NOT-R2-R6: sra $2, $[[T0]], 16 -+ -+ ; R2-R6: subu $[[T0:[0-9]+]], $4, $5 -+ ; R2-R6: seh $2, $[[T0:[0-9]+]] -+ -+ %r = sub i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @sub_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: sub_i32: -+ -+ ; ALL: subu $2, $4, $5 -+ -+ %r = sub i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @sub_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: sub_i64: -+ -+ ; GP32: subu $3, $5, $7 -+ ; GP32: sltu $[[T0:[0-9]+]], $5, $7 -+ ; GP32: addu $[[T1:[0-9]+]], $[[T0]], $6 -+ ; GP32: subu $2, $4, $[[T1]] -+ -+ ; GP64: dsubu $2, $4, $5 -+ -+ %r = sub i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @sub_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: sub_i128: -+ -+ ; GP32: lw $[[T0:[0-9]+]], 20($sp) -+ ; GP32: sltu $[[T1:[0-9]+]], $5, $[[T0]] -+ ; GP32: lw $[[T2:[0-9]+]], 16($sp) -+ ; GP32: addu $[[T3:[0-9]+]], $[[T1]], $[[T2]] -+ ; GP32: lw $[[T4:[0-9]+]], 24($sp) -+ ; GP32: lw $[[T5:[0-9]+]], 28($sp) -+ ; GP32: subu $[[T6:[0-9]+]], $7, $[[T5]] -+ ; GP32: subu $2, $4, $[[T3]] -+ ; GP32: sltu $[[T8:[0-9]+]], $6, $[[T4]] -+ ; GP32: addu $[[T9:[0-9]+]], $[[T8]], $[[T0]] -+ ; GP32: subu $3, $5, $[[T9]] -+ ; GP32: sltu $[[T10:[0-9]+]], $7, $[[T5]] -+ ; GP32: addu $[[T11:[0-9]+]], $[[T10]], $[[T4]] -+ ; GP32: subu $4, $6, $[[T11]] -+ ; GP32: move $5, $[[T6]] -+ -+ ; GP64: dsubu $3, $5, $7 -+ ; GP64: sltu $[[T0:[0-9]+]], $5, $7 -+ ; GP64: daddu $[[T1:[0-9]+]], $[[T0]], $6 -+ ; GP64: dsubu $2, $4, $[[T1]] -+ -+ %r = sub i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/udiv.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/udiv.ll -+++ test/CodeGen/Mips/llvm-ir/udiv.ll -@@ -0,0 +1,108 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=R6 -check-prefix=GP32 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=NOT-R6 -check-prefix=GP64-NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=R6 -check-prefix=64R6 -+ -+define zeroext i1 @udiv_i1(i1 zeroext %a, i1 zeroext %b) { -+entry: -+; ALL-LABEL: udiv_i1: -+ -+ ; NOT-R6: divu $zero, $4, $5 -+ ; NOT-R6: teq $5, $zero, 7 -+ ; NOT-R6: mflo $2 -+ -+ ; R6: divu $2, $4, $5 -+ ; R6: teq $5, $zero, 7 -+ -+ %r = udiv i1 %a, %b -+ ret i1 %r -+} -+ -+define zeroext i8 @udiv_i8(i8 zeroext %a, i8 zeroext %b) { -+entry: -+; ALL-LABEL: udiv_i8: -+ -+ ; NOT-R6: divu $zero, $4, $5 -+ ; NOT-R6: teq $5, $zero, 7 -+ ; NOT-R6: mflo $2 -+ -+ ; R6: divu $2, $4, $5 -+ ; R6: teq $5, $zero, 7 -+ -+ %r = udiv i8 %a, %b -+ ret i8 %r -+} -+ -+define zeroext i16 @udiv_i16(i16 zeroext %a, i16 zeroext %b) { -+entry: -+; ALL-LABEL: udiv_i16: -+ -+ ; NOT-R6: divu $zero, $4, $5 -+ ; NOT-R6: teq $5, $zero, 7 -+ ; NOT-R6: mflo $2 -+ -+ ; R6: divu $2, $4, $5 -+ ; R6: teq $5, $zero, 7 -+ -+ %r = udiv i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @udiv_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: udiv_i32: -+ -+ ; NOT-R6: divu $zero, $4, $5 -+ ; NOT-R6: teq $5, $zero, 7 -+ ; NOT-R6: mflo $2 -+ -+ ; R6: divu $2, $4, $5 -+ ; R6: teq $5, $zero, 7 -+ -+ %r = udiv i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @udiv_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: udiv_i64: -+ -+ ; GP32: lw $25, %call16(__udivdi3)($gp) -+ -+ ; GP64-NOT-R6: ddivu $zero, $4, $5 -+ ; GP64-NOT-R6: teq $5, $zero, 7 -+ ; GP64-NOT-R6: mflo $2 -+ -+ ; 64R6: ddivu $2, $4, $5 -+ ; 64R6: teq $5, $zero, 7 -+ -+ %r = udiv i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @udiv_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: udiv_i128: -+ -+ ; GP32: lw $25, %call16(__udivti3)($gp) -+ -+ ; GP64-NOT-R6: ld $25, %call16(__udivti3)($gp) -+ ; 64-R6: ld $25, %call16(__udivti3)($gp) -+ -+ %r = udiv i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/urem.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/urem.ll -+++ test/CodeGen/Mips/llvm-ir/urem.ll -@@ -0,0 +1,145 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=GP32 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=GP32 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s -check-prefix=GP32 \ -+; RUN: -check-prefix=R2 -check-prefix=R2-R6 -check-prefix=NOT-R6 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=GP32 -check-prefix=R6 -check-prefix=R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -check-prefix=NOT-R2-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=R2 -check-prefix=R2-R6 \ -+; RUN: -check-prefix=GP64-NOT-R6 -check-prefix=NOT-R6 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=64R6 -check-prefix=R6 -check-prefix=R2-R6 -+ -+define signext i1 @urem_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: urem_i1: -+ -+ ; NOT-R6: andi $[[T0:[0-9]+]], $5, 1 -+ ; NOT-R6: andi $[[T1:[0-9]+]], $4, 1 -+ ; NOT-R6: divu $zero, $[[T1]], $[[T0]] -+ ; NOT-R6: teq $[[T0]], $zero, 7 -+ ; NOT-R6: mfhi $[[T2:[0-9]+]] -+ ; NOT-R6: sll $[[T3:[0-9]+]], $[[T2]], 31 -+ ; NOT-R6: sra $2, $[[T3]], 31 -+ -+ ; R6: andi $[[T0:[0-9]+]], $5, 1 -+ ; R6: andi $[[T1:[0-9]+]], $4, 1 -+ ; R6: modu $[[T2:[0-9]+]], $[[T1]], $[[T0]] -+ ; R6: teq $[[T0]], $zero, 7 -+ ; R6: sll $[[T3:[0-9]+]], $[[T2]], 31 -+ ; R6: sra $2, $[[T3]], 31 -+ -+ %r = urem i1 %a, %b -+ ret i1 %r -+} -+ -+define signext i8 @urem_i8(i8 signext %a, i8 signext %b) { -+entry: -+; ALL-LABEL: urem_i8: -+ -+ ; NOT-R2-R6: andi $[[T0:[0-9]+]], $5, 255 -+ ; NOT-R2-R6: andi $[[T1:[0-9]+]], $4, 255 -+ ; NOT-R2-R6: divu $zero, $[[T1]], $[[T0]] -+ ; NOT-R2-R6: teq $[[T0]], $zero, 7 -+ ; NOT-R2-R6: mfhi $[[T2:[0-9]+]] -+ ; NOT-R2-R6: sll $[[T3:[0-9]+]], $[[T2]], 24 -+ ; NOT-R2-R6: sra $2, $[[T3]], 24 -+ -+ ; R2: andi $[[T0:[0-9]+]], $5, 255 -+ ; R2: andi $[[T1:[0-9]+]], $4, 255 -+ ; R2: divu $zero, $[[T1]], $[[T0]] -+ ; R2: teq $[[T0]], $zero, 7 -+ ; R2: mfhi $[[T2:[0-9]+]] -+ ; R2: seb $2, $[[T2]] -+ -+ ; R6: andi $[[T0:[0-9]+]], $5, 255 -+ ; R6: andi $[[T1:[0-9]+]], $4, 255 -+ ; R6: modu $[[T2:[0-9]+]], $[[T1]], $[[T0]] -+ ; R6: teq $[[T0]], $zero, 7 -+ ; R6: seb $2, $[[T2]] -+ -+ %r = urem i8 %a, %b -+ ret i8 %r -+} -+ -+define signext i16 @urem_i16(i16 signext %a, i16 signext %b) { -+entry: -+; ALL-LABEL: urem_i16: -+ -+ ; NOT-R2-R6: andi $[[T0:[0-9]+]], $5, 65535 -+ ; NOT-R2-R6: andi $[[T1:[0-9]+]], $4, 65535 -+ ; NOT-R2-R6: divu $zero, $[[T1]], $[[T0]] -+ ; NOT-R2-R6: teq $[[T0]], $zero, 7 -+ ; NOT-R2-R6: mfhi $[[T2:[0-9]+]] -+ ; NOT-R2-R6: sll $[[T3:[0-9]+]], $[[T2]], 16 -+ ; NOT-R2-R6: sra $2, $[[T3]], 16 -+ -+ ; R2: andi $[[T0:[0-9]+]], $5, 65535 -+ ; R2: andi $[[T1:[0-9]+]], $4, 65535 -+ ; R2: divu $zero, $[[T1]], $[[T0]] -+ ; R2: teq $[[T0]], $zero, 7 -+ ; R2: mfhi $[[T3:[0-9]+]] -+ ; R2: seh $2, $[[T2]] -+ -+ ; R6: andi $[[T0:[0-9]+]], $5, 65535 -+ ; R6: andi $[[T1:[0-9]+]], $4, 65535 -+ ; R6: modu $[[T2:[0-9]+]], $[[T1]], $[[T0]] -+ ; R6: teq $[[T0]], $zero, 7 -+ ; R6: seh $2, $[[T2]] -+ -+ %r = urem i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @urem_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: urem_i32: -+ -+ ; NOT-R6: divu $zero, $4, $5 -+ ; NOT-R6: teq $5, $zero, 7 -+ ; NOT-R6: mfhi $2 -+ -+ ; R6: modu $2, $4, $5 -+ ; R6: teq $5, $zero, 7 -+ -+ %r = urem i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @urem_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: urem_i64: -+ -+ ; GP32: lw $25, %call16(__umoddi3)($gp) -+ -+ ; GP64-NOT-R6: ddivu $zero, $4, $5 -+ ; GP64-NOT-R6: teq $5, $zero, 7 -+ ; GP64-NOT-R6: mfhi $2 -+ -+ ; 64R6: dmodu $2, $4, $5 -+ ; 64R6: teq $5, $zero, 7 -+ -+ %r = urem i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @urem_i128(i128 signext %a, i128 signext %b) { -+entry: -+ ; ALL-LABEL: urem_i128: -+ -+ ; GP32: lw $25, %call16(__umodti3)($gp) -+ -+ ; GP64-NOT-R6: ld $25, %call16(__umodti3)($gp) -+ ; 64-R6: ld $25, %call16(__umodti3)($gp) -+ -+ %r = urem i128 %a, %b -+ ret i128 %r -+} -Index: test/CodeGen/Mips/llvm-ir/xor.ll -=================================================================== ---- test/CodeGen/Mips/llvm-ir/xor.ll -+++ test/CodeGen/Mips/llvm-ir/xor.ll -@@ -0,0 +1,94 @@ -+; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP32 -+; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -+; RUN: -check-prefix=ALL -check-prefix=GP64 -+ -+define signext i1 @xor_i1(i1 signext %a, i1 signext %b) { -+entry: -+; ALL-LABEL: xor_i1: -+ -+ ; ALL: xor $2, $4, $5 -+ -+ %r = xor i1 %a, %b -+ ret i1 %r -+} -+ -+define signext i8 @xor_i8(i8 signext %a, i8 signext %b) { -+entry: -+; ALL-LABEL: xor_i8: -+ -+ ; ALL: xor $2, $4, $5 -+ -+ %r = xor i8 %a, %b -+ ret i8 %r -+} -+ -+define signext i16 @xor_i16(i16 signext %a, i16 signext %b) { -+entry: -+; ALL-LABEL: xor_i16: -+ -+ ; ALL: xor $2, $4, $5 -+ -+ %r = xor i16 %a, %b -+ ret i16 %r -+} -+ -+define signext i32 @xor_i32(i32 signext %a, i32 signext %b) { -+entry: -+; ALL-LABEL: xor_i32: -+ -+ ; GP32: xor $2, $4, $5 -+ -+ ; GP64: xor $[[T0:[0-9]+]], $4, $5 -+ ; GP64: sll $2, $[[T0]], 0 -+ -+ %r = xor i32 %a, %b -+ ret i32 %r -+} -+ -+define signext i64 @xor_i64(i64 signext %a, i64 signext %b) { -+entry: -+; ALL-LABEL: xor_i64: -+ -+ ; GP32: xor $2, $4, $6 -+ ; GP32: xor $3, $5, $7 -+ -+ ; GP64: xor $2, $4, $5 -+ -+ %r = xor i64 %a, %b -+ ret i64 %r -+} -+ -+define signext i128 @xor_i128(i128 signext %a, i128 signext %b) { -+entry: -+; ALL-LABEL: xor_i128: -+ -+ ; GP32: lw $[[T0:[0-9]+]], 24($sp) -+ ; GP32: lw $[[T1:[0-9]+]], 20($sp) -+ ; GP32: lw $[[T2:[0-9]+]], 16($sp) -+ ; GP32: xor $2, $4, $[[T2]] -+ ; GP32: xor $3, $5, $[[T1]] -+ ; GP32: xor $4, $6, $[[T0]] -+ ; GP32: lw $[[T3:[0-9]+]], 28($sp) -+ ; GP32: xor $5, $7, $[[T3]] -+ -+ ; GP64: xor $2, $4, $6 -+ ; GP64: xor $3, $5, $7 -+ -+ %r = xor i128 %a, %b -+ ret i128 %r -+} diff --git a/contrib/llvm/patches/patch-10-llvm-r230348-arm-fix-bad-ha.diff b/contrib/llvm/patches/patch-08-llvm-r230348-arm-fix-bad-ha.diff index 64c558e..2896899 100644 --- a/contrib/llvm/patches/patch-10-llvm-r230348-arm-fix-bad-ha.diff +++ b/contrib/llvm/patches/patch-08-llvm-r230348-arm-fix-bad-ha.diff @@ -67,7 +67,7 @@ Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp } } -@@ -7696,11 +7696,8 @@ void SelectionDAGISel::LowerArguments(const Functi +@@ -7697,11 +7697,8 @@ void SelectionDAGISel::LowerArguments(const Functi } if (F.getAttributes().hasAttribute(Idx, Attribute::Nest)) Flags.setNest(); @@ -80,7 +80,7 @@ Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Flags.setOrigAlign(OriginalAlignment); MVT RegisterVT = TLI->getRegisterType(*CurDAG->getContext(), VT); -@@ -7715,6 +7712,8 @@ void SelectionDAGISel::LowerArguments(const Functi +@@ -7716,6 +7713,8 @@ void SelectionDAGISel::LowerArguments(const Functi MyFlags.Flags.setOrigAlign(1); Ins.push_back(MyFlags); } @@ -287,7 +287,7 @@ Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp -@@ -11280,7 +11280,9 @@ static bool isHomogeneousAggregate(Type *Ty, HABas +@@ -11285,7 +11285,9 @@ static bool isHomogeneousAggregate(Type *Ty, HABas return (Members > 0 && Members <= 4); } @@ -298,7 +298,7 @@ Index: lib/Target/ARM/ARMISelLowering.cpp bool ARMTargetLowering::functionArgumentNeedsConsecutiveRegisters( Type *Ty, CallingConv::ID CallConv, bool isVarArg) const { if (getEffectiveCallingConv(CallConv, isVarArg) != -@@ -11289,7 +11291,9 @@ bool ARMTargetLowering::functionArgumentNeedsConse +@@ -11294,7 +11296,9 @@ bool ARMTargetLowering::functionArgumentNeedsConse HABaseType Base = HA_UNKNOWN; uint64_t Members = 0; diff --git a/contrib/llvm/patches/patch-12-clang-r227115-constantarraytype.diff b/contrib/llvm/patches/patch-09-clang-r227115-constantarraytype.diff index 33ca358..33ca358 100644 --- a/contrib/llvm/patches/patch-12-clang-r227115-constantarraytype.diff +++ b/contrib/llvm/patches/patch-09-clang-r227115-constantarraytype.diff diff --git a/contrib/llvm/patches/patch-09-llvm-r230058-indirectbrs-assert.diff b/contrib/llvm/patches/patch-09-llvm-r230058-indirectbrs-assert.diff deleted file mode 100644 index 1d31c28..0000000 --- a/contrib/llvm/patches/patch-09-llvm-r230058-indirectbrs-assert.diff +++ /dev/null @@ -1,55 +0,0 @@ -Pull in r230058 from upstream llvm trunk (by Benjamin Kramer): - - LoopRotate: When reconstructing loop simplify form don't split edges - from indirectbrs. - - Yet another chapter in the endless story. While this looks like we - leave the loop in a non-canonical state this replicates the logic in - LoopSimplify so it doesn't diverge from the canonical form in any way. - - PR21968 - -This fixes a "Cannot split critical edge from IndirectBrInst" assertion -failure when building the devel/radare2 port. - -Introduced here: https://svnweb.freebsd.org/changeset/base/279161 - -Index: lib/Transforms/Scalar/LoopRotation.cpp -=================================================================== ---- lib/Transforms/Scalar/LoopRotation.cpp -+++ lib/Transforms/Scalar/LoopRotation.cpp -@@ -535,6 +535,8 @@ bool LoopRotate::rotateLoop(Loop *L, bool Simplifi - Loop *PredLoop = LI->getLoopFor(*PI); - if (!PredLoop || PredLoop->contains(Exit)) - continue; -+ if (isa<IndirectBrInst>((*PI)->getTerminator())) -+ continue; - SplitLatchEdge |= L->getLoopLatch() == *PI; - BasicBlock *ExitSplit = SplitCriticalEdge(*PI, Exit, this); - ExitSplit->moveBefore(Exit); -Index: test/Transforms/LoopRotate/crash.ll -=================================================================== ---- test/Transforms/LoopRotate/crash.ll -+++ test/Transforms/LoopRotate/crash.ll -@@ -153,3 +153,21 @@ entry: - "5": ; preds = %"3", %entry - ret void - } -+ -+; PR21968 -+define void @test8(i1 %C, i8* %P) #0 { -+entry: -+ br label %for.cond -+ -+for.cond: ; preds = %for.inc, %entry -+ br i1 %C, label %l_bad, label %for.body -+ -+for.body: ; preds = %for.cond -+ indirectbr i8* %P, [label %for.inc, label %l_bad] -+ -+for.inc: ; preds = %for.body -+ br label %for.cond -+ -+l_bad: ; preds = %for.body, %for.cond -+ ret void -+} diff --git a/contrib/llvm/patches/patch-11-llvm-r231227-aarch64-tls-relocs.diff b/contrib/llvm/patches/patch-11-llvm-r231227-aarch64-tls-relocs.diff deleted file mode 100644 index 5c0edca..0000000 --- a/contrib/llvm/patches/patch-11-llvm-r231227-aarch64-tls-relocs.diff +++ /dev/null @@ -1,811 +0,0 @@ -Pull in r231227 from upstream llvm trunk (by Kristof Beyls): - - Fix PR22408 - LLVM producing AArch64 TLS relocations that GNU linkers - cannot handle yet. - - As is described at http://llvm.org/bugs/show_bug.cgi?id=22408, the - GNU linkers ld.bfd and ld.gold currently only support a subset of the - whole range of AArch64 ELF TLS relocations. Furthermore, they assume - that some of the code sequences to access thread-local variables are - produced in a very specific sequence. When the sequence is not as the - linker expects, it can silently mis-relaxe/mis-optimize the - instructions. - Even if that wouldn't be the case, it's good to produce the exact - sequence, as that ensures that linkers can perform optimizing - relaxations. - - This patch: - - * implements support for 16MiB TLS area size instead of 4GiB TLS area - size. Ideally clang would grow an -mtls-size option to allow - support for both, but that's not part of this patch. - * by default doesn't produce local dynamic access patterns, as even - modern ld.bfd and ld.gold linkers do not support the associated - relocations. An option (-aarch64-elf-ldtls-generation) is added to - enable generation of local dynamic code sequence, but is off by - default. - * makes sure that the exact expected code sequence for local dynamic - and general dynamic accesses is produced, by making use of a new - pseudo instruction. The patch also removes two - (AArch64ISD::TLSDESC_BLR, AArch64ISD::TLSDESC_CALL) pre-existing - AArch64-specific pseudo SDNode instructions that are superseded by - the new one (TLSDESC_CALLSEQ). - -Introduced here: https://svnweb.freebsd.org/changeset/base/280865 - -Index: lib/Target/AArch64/AArch64AsmPrinter.cpp -=================================================================== ---- lib/Target/AArch64/AArch64AsmPrinter.cpp -+++ lib/Target/AArch64/AArch64AsmPrinter.cpp -@@ -12,6 +12,8 @@ - // - //===----------------------------------------------------------------------===// - -+#include "MCTargetDesc/AArch64AddressingModes.h" -+#include "MCTargetDesc/AArch64MCExpr.h" - #include "AArch64.h" - #include "AArch64MCInstLower.h" - #include "AArch64MachineFunctionInfo.h" -@@ -494,12 +496,47 @@ void AArch64AsmPrinter::EmitInstruction(const Mach - EmitToStreamer(OutStreamer, TmpInst); - return; - } -- case AArch64::TLSDESC_BLR: { -- MCOperand Callee, Sym; -- MCInstLowering.lowerOperand(MI->getOperand(0), Callee); -- MCInstLowering.lowerOperand(MI->getOperand(1), Sym); -+ case AArch64::TLSDESC_CALLSEQ: { -+ /// lower this to: -+ /// adrp x0, :tlsdesc:var -+ /// ldr x1, [x0, #:tlsdesc_lo12:var] -+ /// add x0, x0, #:tlsdesc_lo12:var -+ /// .tlsdesccall var -+ /// blr x1 -+ /// (TPIDR_EL0 offset now in x0) -+ const MachineOperand &MO_Sym = MI->getOperand(0); -+ MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym); -+ MCOperand Sym, SymTLSDescLo12, SymTLSDesc; -+ MO_TLSDESC_LO12.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGEOFF | -+ AArch64II::MO_NC); -+ MO_TLSDESC.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGE); -+ MCInstLowering.lowerOperand(MO_Sym, Sym); -+ MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12); -+ MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc); - -- // First emit a relocation-annotation. This expands to no code, but requests -+ MCInst Adrp; -+ Adrp.setOpcode(AArch64::ADRP); -+ Adrp.addOperand(MCOperand::CreateReg(AArch64::X0)); -+ Adrp.addOperand(SymTLSDesc); -+ EmitToStreamer(OutStreamer, Adrp); -+ -+ MCInst Ldr; -+ Ldr.setOpcode(AArch64::LDRXui); -+ Ldr.addOperand(MCOperand::CreateReg(AArch64::X1)); -+ Ldr.addOperand(MCOperand::CreateReg(AArch64::X0)); -+ Ldr.addOperand(SymTLSDescLo12); -+ Ldr.addOperand(MCOperand::CreateImm(0)); -+ EmitToStreamer(OutStreamer, Ldr); -+ -+ MCInst Add; -+ Add.setOpcode(AArch64::ADDXri); -+ Add.addOperand(MCOperand::CreateReg(AArch64::X0)); -+ Add.addOperand(MCOperand::CreateReg(AArch64::X0)); -+ Add.addOperand(SymTLSDescLo12); -+ Add.addOperand(MCOperand::CreateImm(AArch64_AM::getShiftValue(0))); -+ EmitToStreamer(OutStreamer, Add); -+ -+ // Emit a relocation-annotation. This expands to no code, but requests - // the following instruction gets an R_AARCH64_TLSDESC_CALL. - MCInst TLSDescCall; - TLSDescCall.setOpcode(AArch64::TLSDESCCALL); -@@ -506,12 +543,10 @@ void AArch64AsmPrinter::EmitInstruction(const Mach - TLSDescCall.addOperand(Sym); - EmitToStreamer(OutStreamer, TLSDescCall); - -- // Other than that it's just a normal indirect call to the function loaded -- // from the descriptor. -- MCInst BLR; -- BLR.setOpcode(AArch64::BLR); -- BLR.addOperand(Callee); -- EmitToStreamer(OutStreamer, BLR); -+ MCInst Blr; -+ Blr.setOpcode(AArch64::BLR); -+ Blr.addOperand(MCOperand::CreateReg(AArch64::X1)); -+ EmitToStreamer(OutStreamer, Blr); - - return; - } -Index: lib/Target/AArch64/AArch64CleanupLocalDynamicTLSPass.cpp -=================================================================== ---- lib/Target/AArch64/AArch64CleanupLocalDynamicTLSPass.cpp -+++ lib/Target/AArch64/AArch64CleanupLocalDynamicTLSPass.cpp -@@ -62,10 +62,10 @@ struct LDTLSCleanup : public MachineFunctionPass { - for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; - ++I) { - switch (I->getOpcode()) { -- case AArch64::TLSDESC_BLR: -+ case AArch64::TLSDESC_CALLSEQ: - // Make sure it's a local dynamic access. -- if (!I->getOperand(1).isSymbol() || -- strcmp(I->getOperand(1).getSymbolName(), "_TLS_MODULE_BASE_")) -+ if (!I->getOperand(0).isSymbol() || -+ strcmp(I->getOperand(0).getSymbolName(), "_TLS_MODULE_BASE_")) - break; - - if (TLSBaseAddrReg) -Index: lib/Target/AArch64/AArch64ISelLowering.cpp -=================================================================== ---- lib/Target/AArch64/AArch64ISelLowering.cpp -+++ lib/Target/AArch64/AArch64ISelLowering.cpp -@@ -64,10 +64,18 @@ EnableAArch64ExtrGeneration("aarch64-extr-generati - - static cl::opt<bool> - EnableAArch64SlrGeneration("aarch64-shift-insert-generation", cl::Hidden, -- cl::desc("Allow AArch64 SLI/SRI formation"), -- cl::init(false)); -+ cl::desc("Allow AArch64 SLI/SRI formation"), -+ cl::init(false)); - -+// FIXME: The necessary dtprel relocations don't seem to be supported -+// well in the GNU bfd and gold linkers at the moment. Therefore, by -+// default, for now, fall back to GeneralDynamic code generation. -+cl::opt<bool> EnableAArch64ELFLocalDynamicTLSGeneration( -+ "aarch64-elf-ldtls-generation", cl::Hidden, -+ cl::desc("Allow AArch64 Local Dynamic TLS code generation"), -+ cl::init(false)); - -+ - AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM) - : TargetLowering(TM) { - Subtarget = &TM.getSubtarget<AArch64Subtarget>(); -@@ -760,7 +768,7 @@ const char *AArch64TargetLowering::getTargetNodeNa - case AArch64ISD::CSNEG: return "AArch64ISD::CSNEG"; - case AArch64ISD::CSINC: return "AArch64ISD::CSINC"; - case AArch64ISD::THREAD_POINTER: return "AArch64ISD::THREAD_POINTER"; -- case AArch64ISD::TLSDESC_CALL: return "AArch64ISD::TLSDESC_CALL"; -+ case AArch64ISD::TLSDESC_CALLSEQ: return "AArch64ISD::TLSDESC_CALLSEQ"; - case AArch64ISD::ADC: return "AArch64ISD::ADC"; - case AArch64ISD::SBC: return "AArch64ISD::SBC"; - case AArch64ISD::ADDS: return "AArch64ISD::ADDS"; -@@ -3049,61 +3057,34 @@ AArch64TargetLowering::LowerDarwinGlobalTLSAddress - /// When accessing thread-local variables under either the general-dynamic or - /// local-dynamic system, we make a "TLS-descriptor" call. The variable will - /// have a descriptor, accessible via a PC-relative ADRP, and whose first entry --/// is a function pointer to carry out the resolution. This function takes the --/// address of the descriptor in X0 and returns the TPIDR_EL0 offset in X0. All --/// other registers (except LR, NZCV) are preserved. -+/// is a function pointer to carry out the resolution. - /// --/// Thus, the ideal call sequence on AArch64 is: -+/// The sequence is: -+/// adrp x0, :tlsdesc:var -+/// ldr x1, [x0, #:tlsdesc_lo12:var] -+/// add x0, x0, #:tlsdesc_lo12:var -+/// .tlsdesccall var -+/// blr x1 -+/// (TPIDR_EL0 offset now in x0) - /// --/// adrp x0, :tlsdesc:thread_var --/// ldr x8, [x0, :tlsdesc_lo12:thread_var] --/// add x0, x0, :tlsdesc_lo12:thread_var --/// .tlsdesccall thread_var --/// blr x8 --/// (TPIDR_EL0 offset now in x0). --/// --/// The ".tlsdesccall" directive instructs the assembler to insert a particular --/// relocation to help the linker relax this sequence if it turns out to be too --/// conservative. --/// --/// FIXME: we currently produce an extra, duplicated, ADRP instruction, but this --/// is harmless. --SDValue AArch64TargetLowering::LowerELFTLSDescCall(SDValue SymAddr, -- SDValue DescAddr, SDLoc DL, -- SelectionDAG &DAG) const { -+/// The above sequence must be produced unscheduled, to enable the linker to -+/// optimize/relax this sequence. -+/// Therefore, a pseudo-instruction (TLSDESC_CALLSEQ) is used to represent the -+/// above sequence, and expanded really late in the compilation flow, to ensure -+/// the sequence is produced as per above. -+SDValue AArch64TargetLowering::LowerELFTLSDescCallSeq(SDValue SymAddr, SDLoc DL, -+ SelectionDAG &DAG) const { - EVT PtrVT = getPointerTy(); - -- // The function we need to call is simply the first entry in the GOT for this -- // descriptor, load it in preparation. -- SDValue Func = DAG.getNode(AArch64ISD::LOADgot, DL, PtrVT, SymAddr); -+ SDValue Chain = DAG.getEntryNode(); -+ SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); - -- // TLS calls preserve all registers except those that absolutely must be -- // trashed: X0 (it takes an argument), LR (it's a call) and NZCV (let's not be -- // silly). -- const TargetRegisterInfo *TRI = -- getTargetMachine().getSubtargetImpl()->getRegisterInfo(); -- const AArch64RegisterInfo *ARI = -- static_cast<const AArch64RegisterInfo *>(TRI); -- const uint32_t *Mask = ARI->getTLSCallPreservedMask(); -- -- // The function takes only one argument: the address of the descriptor itself -- // in X0. -- SDValue Glue, Chain; -- Chain = DAG.getCopyToReg(DAG.getEntryNode(), DL, AArch64::X0, DescAddr, Glue); -- Glue = Chain.getValue(1); -- -- // We're now ready to populate the argument list, as with a normal call: -- SmallVector<SDValue, 6> Ops; -+ SmallVector<SDValue, 2> Ops; - Ops.push_back(Chain); -- Ops.push_back(Func); - Ops.push_back(SymAddr); -- Ops.push_back(DAG.getRegister(AArch64::X0, PtrVT)); -- Ops.push_back(DAG.getRegisterMask(Mask)); -- Ops.push_back(Glue); - -- SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); -- Chain = DAG.getNode(AArch64ISD::TLSDESC_CALL, DL, NodeTys, Ops); -- Glue = Chain.getValue(1); -+ Chain = DAG.getNode(AArch64ISD::TLSDESC_CALLSEQ, DL, NodeTys, Ops); -+ SDValue Glue = Chain.getValue(1); - - return DAG.getCopyFromReg(Chain, DL, AArch64::X0, PtrVT, Glue); - } -@@ -3114,9 +3095,18 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SD - assert(Subtarget->isTargetELF() && "This function expects an ELF target"); - assert(getTargetMachine().getCodeModel() == CodeModel::Small && - "ELF TLS only supported in small memory model"); -+ // Different choices can be made for the maximum size of the TLS area for a -+ // module. For the small address model, the default TLS size is 16MiB and the -+ // maximum TLS size is 4GiB. -+ // FIXME: add -mtls-size command line option and make it control the 16MiB -+ // vs. 4GiB code sequence generation. - const GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op); - - TLSModel::Model Model = getTargetMachine().getTLSModel(GA->getGlobal()); -+ if (!EnableAArch64ELFLocalDynamicTLSGeneration) { -+ if (Model == TLSModel::LocalDynamic) -+ Model = TLSModel::GeneralDynamic; -+ } - - SDValue TPOff; - EVT PtrVT = getPointerTy(); -@@ -3127,17 +3117,20 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SD - - if (Model == TLSModel::LocalExec) { - SDValue HiVar = DAG.getTargetGlobalAddress( -- GV, DL, PtrVT, 0, AArch64II::MO_TLS | AArch64II::MO_G1); -+ GV, DL, PtrVT, 0, AArch64II::MO_TLS | AArch64II::MO_HI12); - SDValue LoVar = DAG.getTargetGlobalAddress( - GV, DL, PtrVT, 0, -- AArch64II::MO_TLS | AArch64II::MO_G0 | AArch64II::MO_NC); -+ AArch64II::MO_TLS | AArch64II::MO_PAGEOFF | AArch64II::MO_NC); - -- TPOff = SDValue(DAG.getMachineNode(AArch64::MOVZXi, DL, PtrVT, HiVar, -- DAG.getTargetConstant(16, MVT::i32)), -- 0); -- TPOff = SDValue(DAG.getMachineNode(AArch64::MOVKXi, DL, PtrVT, TPOff, LoVar, -- DAG.getTargetConstant(0, MVT::i32)), -- 0); -+ SDValue TPWithOff_lo = -+ SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, ThreadBase, -+ HiVar, DAG.getTargetConstant(0, MVT::i32)), -+ 0); -+ SDValue TPWithOff = -+ SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, TPWithOff_lo, -+ LoVar, DAG.getTargetConstant(0, MVT::i32)), -+ 0); -+ return TPWithOff; - } else if (Model == TLSModel::InitialExec) { - TPOff = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, AArch64II::MO_TLS); - TPOff = DAG.getNode(AArch64ISD::LOADgot, DL, PtrVT, TPOff); -@@ -3152,19 +3145,6 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SD - DAG.getMachineFunction().getInfo<AArch64FunctionInfo>(); - MFI->incNumLocalDynamicTLSAccesses(); - -- // Accesses used in this sequence go via the TLS descriptor which lives in -- // the GOT. Prepare an address we can use to handle this. -- SDValue HiDesc = DAG.getTargetExternalSymbol( -- "_TLS_MODULE_BASE_", PtrVT, AArch64II::MO_TLS | AArch64II::MO_PAGE); -- SDValue LoDesc = DAG.getTargetExternalSymbol( -- "_TLS_MODULE_BASE_", PtrVT, -- AArch64II::MO_TLS | AArch64II::MO_PAGEOFF | AArch64II::MO_NC); -- -- // First argument to the descriptor call is the address of the descriptor -- // itself. -- SDValue DescAddr = DAG.getNode(AArch64ISD::ADRP, DL, PtrVT, HiDesc); -- DescAddr = DAG.getNode(AArch64ISD::ADDlow, DL, PtrVT, DescAddr, LoDesc); -- - // The call needs a relocation too for linker relaxation. It doesn't make - // sense to call it MO_PAGE or MO_PAGEOFF though so we need another copy of - // the address. -@@ -3173,40 +3153,23 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SD - - // Now we can calculate the offset from TPIDR_EL0 to this module's - // thread-local area. -- TPOff = LowerELFTLSDescCall(SymAddr, DescAddr, DL, DAG); -+ TPOff = LowerELFTLSDescCallSeq(SymAddr, DL, DAG); - - // Now use :dtprel_whatever: operations to calculate this variable's offset - // in its thread-storage area. - SDValue HiVar = DAG.getTargetGlobalAddress( -- GV, DL, MVT::i64, 0, AArch64II::MO_TLS | AArch64II::MO_G1); -+ GV, DL, MVT::i64, 0, AArch64II::MO_TLS | AArch64II::MO_HI12); - SDValue LoVar = DAG.getTargetGlobalAddress( - GV, DL, MVT::i64, 0, -- AArch64II::MO_TLS | AArch64II::MO_G0 | AArch64II::MO_NC); -+ AArch64II::MO_TLS | AArch64II::MO_PAGEOFF | AArch64II::MO_NC); - -- SDValue DTPOff = -- SDValue(DAG.getMachineNode(AArch64::MOVZXi, DL, PtrVT, HiVar, -- DAG.getTargetConstant(16, MVT::i32)), -- 0); -- DTPOff = -- SDValue(DAG.getMachineNode(AArch64::MOVKXi, DL, PtrVT, DTPOff, LoVar, -- DAG.getTargetConstant(0, MVT::i32)), -- 0); -- -- TPOff = DAG.getNode(ISD::ADD, DL, PtrVT, TPOff, DTPOff); -+ TPOff = SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, TPOff, HiVar, -+ DAG.getTargetConstant(0, MVT::i32)), -+ 0); -+ TPOff = SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, TPOff, LoVar, -+ DAG.getTargetConstant(0, MVT::i32)), -+ 0); - } else if (Model == TLSModel::GeneralDynamic) { -- // Accesses used in this sequence go via the TLS descriptor which lives in -- // the GOT. Prepare an address we can use to handle this. -- SDValue HiDesc = DAG.getTargetGlobalAddress( -- GV, DL, PtrVT, 0, AArch64II::MO_TLS | AArch64II::MO_PAGE); -- SDValue LoDesc = DAG.getTargetGlobalAddress( -- GV, DL, PtrVT, 0, -- AArch64II::MO_TLS | AArch64II::MO_PAGEOFF | AArch64II::MO_NC); -- -- // First argument to the descriptor call is the address of the descriptor -- // itself. -- SDValue DescAddr = DAG.getNode(AArch64ISD::ADRP, DL, PtrVT, HiDesc); -- DescAddr = DAG.getNode(AArch64ISD::ADDlow, DL, PtrVT, DescAddr, LoDesc); -- - // The call needs a relocation too for linker relaxation. It doesn't make - // sense to call it MO_PAGE or MO_PAGEOFF though so we need another copy of - // the address. -@@ -3214,7 +3177,7 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SD - DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, AArch64II::MO_TLS); - - // Finally we can make a call to calculate the offset from tpidr_el0. -- TPOff = LowerELFTLSDescCall(SymAddr, DescAddr, DL, DAG); -+ TPOff = LowerELFTLSDescCallSeq(SymAddr, DL, DAG); - } else - llvm_unreachable("Unsupported ELF TLS access model"); - -Index: lib/Target/AArch64/AArch64ISelLowering.h -=================================================================== ---- lib/Target/AArch64/AArch64ISelLowering.h -+++ lib/Target/AArch64/AArch64ISelLowering.h -@@ -29,9 +29,9 @@ enum { - WrapperLarge, // 4-instruction MOVZ/MOVK sequence for 64-bit addresses. - CALL, // Function call. - -- // Almost the same as a normal call node, except that a TLSDesc relocation is -- // needed so the linker can relax it correctly if possible. -- TLSDESC_CALL, -+ // Produces the full sequence of instructions for getting the thread pointer -+ // offset of a variable into X0, using the TLSDesc model. -+ TLSDESC_CALLSEQ, - ADRP, // Page address of a TargetGlobalAddress operand. - ADDlow, // Add the low 12 bits of a TargetGlobalAddress operand. - LOADgot, // Load from automatically generated descriptor (e.g. Global -@@ -399,8 +399,8 @@ class AArch64TargetLowering : public TargetLowerin - SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerDarwinGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerELFGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; -- SDValue LowerELFTLSDescCall(SDValue SymAddr, SDValue DescAddr, SDLoc DL, -- SelectionDAG &DAG) const; -+ SDValue LowerELFTLSDescCallSeq(SDValue SymAddr, SDLoc DL, -+ SelectionDAG &DAG) const; - SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const; -Index: lib/Target/AArch64/AArch64InstrInfo.td -=================================================================== ---- lib/Target/AArch64/AArch64InstrInfo.td -+++ lib/Target/AArch64/AArch64InstrInfo.td -@@ -96,6 +96,19 @@ def SDT_AArch64ITOF : SDTypeProfile<1, 1, [SDTCis - - def SDT_AArch64TLSDescCall : SDTypeProfile<0, -2, [SDTCisPtrTy<0>, - SDTCisPtrTy<1>]>; -+ -+// Generates the general dynamic sequences, i.e. -+// adrp x0, :tlsdesc:var -+// ldr x1, [x0, #:tlsdesc_lo12:var] -+// add x0, x0, #:tlsdesc_lo12:var -+// .tlsdesccall var -+// blr x1 -+ -+// (the TPIDR_EL0 offset is put directly in X0, hence no "result" here) -+// number of operands (the variable) -+def SDT_AArch64TLSDescCallSeq : SDTypeProfile<0,1, -+ [SDTCisPtrTy<0>]>; -+ - def SDT_AArch64WrapperLarge : SDTypeProfile<1, 4, - [SDTCisVT<0, i64>, SDTCisVT<1, i32>, - SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, -@@ -229,11 +242,12 @@ def AArch64Prefetch : SDNode<"AArch64ISD::P - def AArch64sitof: SDNode<"AArch64ISD::SITOF", SDT_AArch64ITOF>; - def AArch64uitof: SDNode<"AArch64ISD::UITOF", SDT_AArch64ITOF>; - --def AArch64tlsdesc_call : SDNode<"AArch64ISD::TLSDESC_CALL", -- SDT_AArch64TLSDescCall, -- [SDNPInGlue, SDNPOutGlue, SDNPHasChain, -- SDNPVariadic]>; -+def AArch64tlsdesc_callseq : SDNode<"AArch64ISD::TLSDESC_CALLSEQ", -+ SDT_AArch64TLSDescCallSeq, -+ [SDNPInGlue, SDNPOutGlue, SDNPHasChain, -+ SDNPVariadic]>; - -+ - def AArch64WrapperLarge : SDNode<"AArch64ISD::WrapperLarge", - SDT_AArch64WrapperLarge>; - -@@ -1049,15 +1063,16 @@ def TLSDESCCALL : Pseudo<(outs), (ins i64imm:$sym) - let AsmString = ".tlsdesccall $sym"; - } - --// Pseudo-instruction representing a BLR with attached TLSDESC relocation. It --// gets expanded to two MCInsts during lowering. --let isCall = 1, Defs = [LR] in --def TLSDESC_BLR -- : Pseudo<(outs), (ins GPR64:$dest, i64imm:$sym), -- [(AArch64tlsdesc_call GPR64:$dest, tglobaltlsaddr:$sym)]>; -+// FIXME: maybe the scratch register used shouldn't be fixed to X1? -+// FIXME: can "hasSideEffects be dropped? -+let isCall = 1, Defs = [LR, X0, X1], hasSideEffects = 1, -+ isCodeGenOnly = 1 in -+def TLSDESC_CALLSEQ -+ : Pseudo<(outs), (ins i64imm:$sym), -+ [(AArch64tlsdesc_callseq tglobaltlsaddr:$sym)]>; -+def : Pat<(AArch64tlsdesc_callseq texternalsym:$sym), -+ (TLSDESC_CALLSEQ texternalsym:$sym)>; - --def : Pat<(AArch64tlsdesc_call GPR64:$dest, texternalsym:$sym), -- (TLSDESC_BLR GPR64:$dest, texternalsym:$sym)>; - //===----------------------------------------------------------------------===// - // Conditional branch (immediate) instruction. - //===----------------------------------------------------------------------===// -Index: lib/Target/AArch64/AArch64MCInstLower.cpp -=================================================================== ---- lib/Target/AArch64/AArch64MCInstLower.cpp -+++ lib/Target/AArch64/AArch64MCInstLower.cpp -@@ -22,9 +22,12 @@ - #include "llvm/MC/MCExpr.h" - #include "llvm/MC/MCInst.h" - #include "llvm/Support/CodeGen.h" -+#include "llvm/Support/CommandLine.h" - #include "llvm/Target/TargetMachine.h" - using namespace llvm; - -+extern cl::opt<bool> EnableAArch64ELFLocalDynamicTLSGeneration; -+ - AArch64MCInstLower::AArch64MCInstLower(MCContext &ctx, AsmPrinter &printer) - : Ctx(ctx), Printer(printer), TargetTriple(printer.getTargetTriple()) {} - -@@ -84,10 +87,16 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandEL - if (MO.isGlobal()) { - const GlobalValue *GV = MO.getGlobal(); - Model = Printer.TM.getTLSModel(GV); -+ if (!EnableAArch64ELFLocalDynamicTLSGeneration && -+ Model == TLSModel::LocalDynamic) -+ Model = TLSModel::GeneralDynamic; -+ - } else { - assert(MO.isSymbol() && - StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" && - "unexpected external TLS symbol"); -+ // The general dynamic access sequence is used to get the -+ // address of _TLS_MODULE_BASE_. - Model = TLSModel::GeneralDynamic; - } - switch (Model) { -@@ -123,6 +132,8 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandEL - RefFlags |= AArch64MCExpr::VK_G1; - else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0) - RefFlags |= AArch64MCExpr::VK_G0; -+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_HI12) -+ RefFlags |= AArch64MCExpr::VK_HI12; - - if (MO.getTargetFlags() & AArch64II::MO_NC) - RefFlags |= AArch64MCExpr::VK_NC; -Index: lib/Target/AArch64/Utils/AArch64BaseInfo.h -=================================================================== ---- lib/Target/AArch64/Utils/AArch64BaseInfo.h -+++ lib/Target/AArch64/Utils/AArch64BaseInfo.h -@@ -1229,7 +1229,7 @@ namespace AArch64II { - - MO_NO_FLAG, - -- MO_FRAGMENT = 0x7, -+ MO_FRAGMENT = 0xf, - - /// MO_PAGE - A symbol operand with this flag represents the pc-relative - /// offset of the 4K page containing the symbol. This is used with the -@@ -1257,26 +1257,31 @@ namespace AArch64II { - /// 0-15 of a 64-bit address, used in a MOVZ or MOVK instruction - MO_G0 = 6, - -+ /// MO_HI12 - This flag indicates that a symbol operand represents the bits -+ /// 13-24 of a 64-bit address, used in a arithmetic immediate-shifted-left- -+ /// by-12-bits instruction. -+ MO_HI12 = 7, -+ - /// MO_GOT - This flag indicates that a symbol operand represents the - /// address of the GOT entry for the symbol, rather than the address of - /// the symbol itself. -- MO_GOT = 8, -+ MO_GOT = 0x10, - - /// MO_NC - Indicates whether the linker is expected to check the symbol - /// reference for overflow. For example in an ADRP/ADD pair of relocations - /// the ADRP usually does check, but not the ADD. -- MO_NC = 0x10, -+ MO_NC = 0x20, - - /// MO_TLS - Indicates that the operand being accessed is some kind of - /// thread-local symbol. On Darwin, only one type of thread-local access - /// exists (pre linker-relaxation), but on ELF the TLSModel used for the - /// referee will affect interpretation. -- MO_TLS = 0x20, -+ MO_TLS = 0x40, - - /// MO_CONSTPOOL - This flag indicates that a symbol operand represents - /// the address of a constant pool entry for the symbol, rather than the - /// address of the symbol itself. -- MO_CONSTPOOL = 0x40 -+ MO_CONSTPOOL = 0x80 - }; - } // end namespace AArch64II - -Index: test/CodeGen/AArch64/arm64-tls-dynamics.ll -=================================================================== ---- test/CodeGen/AArch64/arm64-tls-dynamics.ll -+++ test/CodeGen/AArch64/arm64-tls-dynamics.ll -@@ -1,5 +1,7 @@ --; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s -+; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -verify-machineinstrs < %s | FileCheck %s -+; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s -+; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-NOLD %s -+; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-NOLD-RELOC %s - - @general_dynamic_var = external thread_local global i32 - -@@ -9,22 +11,34 @@ define i32 @test_generaldynamic() { - %val = load i32* @general_dynamic_var - ret i32 %val - -- ; FIXME: the adrp instructions are redundant (if harmless). --; CHECK: adrp [[TLSDESC_HI:x[0-9]+]], :tlsdesc:general_dynamic_var --; CHECK: add x0, [[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var - ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var --; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var] --; CHECK: .tlsdesccall general_dynamic_var -+; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var] -+; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var -+; CHECK-NEXT: .tlsdesccall general_dynamic_var - ; CHECK-NEXT: blr [[CALLEE]] - -+; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var -+; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var] -+; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var -+; CHECK-NOLD-NEXT: .tlsdesccall general_dynamic_var -+; CHECK-NOLD-NEXT: blr [[CALLEE]] -+ -+ - ; CHECK: mrs x[[TP:[0-9]+]], TPIDR_EL0 - ; CHECK: ldr w0, [x[[TP]], x0] -+; CHECK-NOLD: mrs x[[TP:[0-9]+]], TPIDR_EL0 -+; CHECK-NOLD: ldr w0, [x[[TP]], x0] - - ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21 -+; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC - ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC --; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC - ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL - -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21 -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL -+ - } - - define i32* @test_generaldynamic_addr() { -@@ -32,12 +46,10 @@ define i32* @test_generaldynamic_addr() { - - ret i32* @general_dynamic_var - -- ; FIXME: the adrp instructions are redundant (if harmless). --; CHECK: adrp [[TLSDESC_HI:x[0-9]+]], :tlsdesc:general_dynamic_var --; CHECK: add x0, [[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var - ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var --; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var] --; CHECK: .tlsdesccall general_dynamic_var -+; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var] -+; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var -+; CHECK-NEXT: .tlsdesccall general_dynamic_var - ; CHECK-NEXT: blr [[CALLEE]] - - ; CHECK: mrs [[TP:x[0-9]+]], TPIDR_EL0 -@@ -44,9 +56,15 @@ define i32* @test_generaldynamic_addr() { - ; CHECK: add x0, [[TP]], x0 - - ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21 -+; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC - ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC --; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC - ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL -+ -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21 -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL -+ - } - - @local_dynamic_var = external thread_local(localdynamic) global i32 -@@ -58,54 +76,71 @@ define i32 @test_localdynamic() { - ret i32 %val - - ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ --; CHECK: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_ --; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ --; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_] --; CHECK: .tlsdesccall _TLS_MODULE_BASE_ -+; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_] -+; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_ -+; CHECK-NEXT: .tlsdesccall _TLS_MODULE_BASE_ - ; CHECK-NEXT: blr [[CALLEE]] -+; CHECK-NEXT: add x[[TPOFF:[0-9]+]], x0, :dtprel_hi12:local_dynamic_var -+; CHECK-NEXT: add x[[TPOFF]], x[[TPOFF]], :dtprel_lo12_nc:local_dynamic_var -+; CHECK: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0 -+; CHECK: ldr w0, [x[[TPIDR]], x[[TPOFF]]] - --; CHECK: movz [[DTP_OFFSET:x[0-9]+]], #:dtprel_g1:local_dynamic_var --; CHECK: movk [[DTP_OFFSET]], #:dtprel_g0_nc:local_dynamic_var -+; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:local_dynamic_var -+; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var] -+; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var -+; CHECK-NOLD-NEXT: .tlsdesccall local_dynamic_var -+; CHECK-NOLD-NEXT: blr [[CALLEE]] -+; CHECK-NOLD: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0 -+; CHECK-NOLD: ldr w0, [x[[TPIDR]], x0] - --; CHECK: add x[[TPREL:[0-9]+]], x0, [[DTP_OFFSET]] - --; CHECK: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0 -- --; CHECK: ldr w0, [x[[TPIDR]], x[[TPREL]]] -- - ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21 -+; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC - ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC --; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC - ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL -+; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_HI12 -+; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC - -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21 -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL -+ - } - - define i32* @test_localdynamic_addr() { - ; CHECK-LABEL: test_localdynamic_addr: - -- ret i32* @local_dynamic_var -- - ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ --; CHECK: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_ --; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ --; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_] --; CHECK: .tlsdesccall _TLS_MODULE_BASE_ -+; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_] -+; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_ -+; CHECK-NEXT: .tlsdesccall _TLS_MODULE_BASE_ - ; CHECK-NEXT: blr [[CALLEE]] -+; CHECK-NEXT: add x[[TPOFF:[0-9]+]], x0, :dtprel_hi12:local_dynamic_var -+; CHECK-NEXT: add x[[TPOFF]], x[[TPOFF]], :dtprel_lo12_nc:local_dynamic_var -+; CHECK: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0 -+; CHECK: add x0, x[[TPIDR]], x[[TPOFF]] - --; CHECK: movz [[DTP_OFFSET:x[0-9]+]], #:dtprel_g1:local_dynamic_var --; CHECK: movk [[DTP_OFFSET]], #:dtprel_g0_nc:local_dynamic_var -+; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:local_dynamic_var -+; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var] -+; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var -+; CHECK-NOLD-NEXT: .tlsdesccall local_dynamic_var -+; CHECK-NOLD-NEXT: blr [[CALLEE]] -+; CHECK-NOLD: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0 -+; CHECK-NOLD: add x0, x[[TPIDR]], x0 -+ ret i32* @local_dynamic_var - --; CHECK: add [[TPREL:x[0-9]+]], x0, [[DTP_OFFSET]] -- --; CHECK: mrs [[TPIDR:x[0-9]+]], TPIDR_EL0 -- --; CHECK: add x0, [[TPIDR]], [[TPREL]] -- - ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21 -+; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC - ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC --; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC - ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL -+; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_HI12 -+; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC - -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21 -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC -+; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL - } - - ; The entire point of the local-dynamic access model is to have a single call to -@@ -122,11 +157,10 @@ define i32 @test_localdynamic_deduplicate() { - %sum = add i32 %val, %val2 - ret i32 %sum - --; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ --; CHECK: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_ --; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ --; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_] --; CHECK: .tlsdesccall _TLS_MODULE_BASE_ -+; CHECK: adrp x[[DTPREL_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ -+; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[DTPREL_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_] -+; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE -+; CHECK-NEXT: .tlsdesccall _TLS_MODULE_BASE_ - ; CHECK-NEXT: blr [[CALLEE]] - - ; CHECK-NOT: _TLS_MODULE_BASE_ -Index: test/CodeGen/AArch64/arm64-tls-execs.ll -=================================================================== ---- test/CodeGen/AArch64/arm64-tls-execs.ll -+++ test/CodeGen/AArch64/arm64-tls-execs.ll -@@ -38,14 +38,13 @@ define i32 @test_local_exec() { - ; CHECK-LABEL: test_local_exec: - %val = load i32* @local_exec_var - --; CHECK: movz [[TP_OFFSET:x[0-9]+]], #:tprel_g1:local_exec_var // encoding: [0bAAA{{[01]+}},A,0b101AAAAA,0x92] --; CHECK: movk [[TP_OFFSET]], #:tprel_g0_nc:local_exec_var --; CHECK: mrs x[[TP:[0-9]+]], TPIDR_EL0 --; CHECK: ldr w0, [x[[TP]], [[TP_OFFSET]]] -+; CHECK: mrs x[[R1:[0-9]+]], TPIDR_EL0 -+; CHECK: add x[[R2:[0-9]+]], x[[R1]], :tprel_hi12:local_exec_var -+; CHECK: add x[[R3:[0-9]+]], x[[R2]], :tprel_lo12_nc:local_exec_var -+; CHECK: ldr w0, [x[[R3]]] - --; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G1 --; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G0_NC -- -+; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12 -+; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC - ret i32 %val - } - -@@ -53,11 +52,11 @@ define i32* @test_local_exec_addr() { - ; CHECK-LABEL: test_local_exec_addr: - ret i32* @local_exec_var - --; CHECK: movz [[TP_OFFSET:x[0-9]+]], #:tprel_g1:local_exec_var --; CHECK: movk [[TP_OFFSET]], #:tprel_g0_nc:local_exec_var --; CHECK: mrs [[TP:x[0-9]+]], TPIDR_EL0 --; CHECK: add x0, [[TP]], [[TP_OFFSET]] -+; CHECK: mrs x[[R1:[0-9]+]], TPIDR_EL0 -+; CHECK: add x[[R2:[0-9]+]], x[[R1]], :tprel_hi12:local_exec_var -+; CHECK: add x0, x[[R2]], :tprel_lo12_nc:local_exec_var -+; CHECK: ret - --; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G1 --; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G0_NC -+; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12 -+; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC - } diff --git a/contrib/llvm/patches/patch-13-llvm-r229911-uleb128-commas.diff b/contrib/llvm/patches/patch-13-llvm-r229911-uleb128-commas.diff deleted file mode 100644 index bf13463..0000000 --- a/contrib/llvm/patches/patch-13-llvm-r229911-uleb128-commas.diff +++ /dev/null @@ -1,77 +0,0 @@ -Pull in r229911 from upstream llvm trunk (by Benjamin Kramer): - - MC: Allow multiple comma-separated expressions on the .uleb128 directive. - - For compatiblity with GNU as. Binutils documents this as - '.uleb128 expressions'. Subtle, isn't it? - -Introduced here: http://svnweb.freebsd.org/changeset/base/281775 - -Index: lib/MC/MCParser/AsmParser.cpp -=================================================================== ---- lib/MC/MCParser/AsmParser.cpp -+++ lib/MC/MCParser/AsmParser.cpp -@@ -3636,22 +3636,28 @@ bool AsmParser::parseDirectiveSpace(StringRef IDVa - } - - /// parseDirectiveLEB128 --/// ::= (.sleb128 | .uleb128) expression -+/// ::= (.sleb128 | .uleb128) [ expression (, expression)* ] - bool AsmParser::parseDirectiveLEB128(bool Signed) { - checkForValidSection(); - const MCExpr *Value; - -- if (parseExpression(Value)) -- return true; -+ for (;;) { -+ if (parseExpression(Value)) -+ return true; - -- if (getLexer().isNot(AsmToken::EndOfStatement)) -- return TokError("unexpected token in directive"); -+ if (Signed) -+ getStreamer().EmitSLEB128Value(Value); -+ else -+ getStreamer().EmitULEB128Value(Value); - -- if (Signed) -- getStreamer().EmitSLEB128Value(Value); -- else -- getStreamer().EmitULEB128Value(Value); -+ if (getLexer().is(AsmToken::EndOfStatement)) -+ break; - -+ if (getLexer().isNot(AsmToken::Comma)) -+ return TokError("unexpected token in directive"); -+ Lex(); -+ } -+ - return false; - } - -Index: test/MC/ELF/uleb.s -=================================================================== ---- test/MC/ELF/uleb.s -+++ test/MC/ELF/uleb.s -@@ -11,16 +11,17 @@ foo: - .uleb128 128 - .uleb128 16383 - .uleb128 16384 -+ .uleb128 23, 42 - - // ELF_32: Name: .text - // ELF_32: SectionData ( --// ELF_32: 0000: 00017F80 01FF7F80 8001 -+// ELF_32: 0000: 00017F80 01FF7F80 8001172A - // ELF_32: ) - // ELF_64: Name: .text - // ELF_64: SectionData ( --// ELF_64: 0000: 00017F80 01FF7F80 8001 -+// ELF_64: 0000: 00017F80 01FF7F80 8001172A - // ELF_64: ) - // MACHO_32: ('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') --// MACHO_32: ('_section_data', '00017f80 01ff7f80 8001') -+// MACHO_32: ('_section_data', '00017f80 01ff7f80 8001172a') - // MACHO_64: ('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') --// MACHO_64: ('_section_data', '00017f80 01ff7f80 8001') -+// MACHO_64: ('_section_data', '00017f80 01ff7f80 8001172a') |