diff --git a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp index 199474fbd82d7..dc8feea3408d1 100644 --- a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp +++ b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp @@ -433,13 +433,24 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( Register OldVal = I->getOperand(6).getReg(); Register BinOpRes = I->getOperand(7).getReg(); Register StoreVal = I->getOperand(8).getReg(); + bool NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4() && !STI->hasMips32(); const BasicBlock *LLVM_BB = BB.getBasicBlock(); MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *loop1MBB; + MachineBasicBlock *loop2MBB; + if (NoMovnInstr) { + loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB); + loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB); + } MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); MachineFunction::iterator It = ++BB.getIterator(); MF->insert(It, loopMBB); + if (NoMovnInstr) { + MF->insert(It, loop1MBB); + MF->insert(It, loop2MBB); + } MF->insert(It, sinkMBB); MF->insert(It, exitMBB); @@ -447,9 +458,19 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( exitMBB->transferSuccessorsAndUpdatePHIs(&BB); BB.addSuccessor(loopMBB, BranchProbability::getOne()); - loopMBB->addSuccessor(sinkMBB); - loopMBB->addSuccessor(loopMBB); + if (NoMovnInstr) { + loopMBB->addSuccessor(loop1MBB); + loopMBB->addSuccessor(loop2MBB); + } else { + loopMBB->addSuccessor(sinkMBB); + loopMBB->addSuccessor(loopMBB); + } loopMBB->normalizeSuccProbs(); + if (NoMovnInstr) { + loop1MBB->addSuccessor(loop2MBB); + loop2MBB->addSuccessor(loopMBB); + loop2MBB->addSuccessor(exitMBB, BranchProbability::getOne()); + } BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0); if (IsNand) { @@ -526,7 +547,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( BuildMI(loopMBB, DL, TII->get(OR), BinOpRes) .addReg(BinOpRes) .addReg(Scratch4); - } else { + } else if (STI->hasMips4() || STI->hasMips32()) { // max: move BinOpRes, StoreVal // movn BinOpRes, Incr, Scratch4, BinOpRes // min: move BinOpRes, StoreVal @@ -538,12 +559,59 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( .addReg(Incr) .addReg(Scratch4) .addReg(BinOpRes); + } else { + // if min: + // loopMBB: move BinOpRes, StoreVal + // beq Scratch4, 0, loop1MBB + // j loop2MBB + // loop1MBB: move BinOpRes, Incr + // loop2MBB: and BinOpRes, BinOpRes, Mask + // and StoreVal, OlddVal, Mask2 + // or StoreVal, StoreVal, BinOpRes + // StoreVal = sc StoreVal, 0(Ptr) + // beq StoreVal, zero, loopMBB + // + // if max: + // loopMBB: move BinOpRes, Incr + // beq Scratch4, 0, loop1MBB + // j loop2MBB + // loop1MBB: move BinOpRes, StoreVal + // loop2MBB: and BinOpRes, BinOpRes, Mask + // and StoreVal, OlddVal, Mask2 + // or StoreVal, StoreVal, BinOpRes + // StoreVal = sc StoreVal, 0(Ptr) + // beq StoreVal, zero, loopMBB + if (IsMin) { + BuildMI(loopMBB, DL, TII->get(OR), BinOpRes) + .addReg(StoreVal) + .addReg(Mips::ZERO); + BuildMI(loop1MBB, DL, TII->get(OR), BinOpRes) + .addReg(Incr) + .addReg(Mips::ZERO); + } else { + BuildMI(loopMBB, DL, TII->get(OR), BinOpRes) + .addReg(Incr) + .addReg(Mips::ZERO); + BuildMI(loop1MBB, DL, TII->get(OR), BinOpRes) + .addReg(StoreVal) + .addReg(Mips::ZERO); + } + BuildMI(loopMBB, DL, TII->get(BEQ)) + .addReg(Scratch4) + .addReg(Mips::ZERO) + .addMBB(loop1MBB); + BuildMI(loopMBB, DL, TII->get(Mips::B)).addMBB(loop2MBB); } // and BinOpRes, BinOpRes, Mask - BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes) - .addReg(BinOpRes) - .addReg(Mask); + if (NoMovnInstr) + BuildMI(loop2MBB, DL, TII->get(Mips::AND), BinOpRes) + .addReg(BinOpRes) + .addReg(Mask); + else + BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes) + .addReg(BinOpRes) + .addReg(Mask); } else if (!IsSwap) { // binopres, oldval, incr2 @@ -565,14 +633,37 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( // or StoreVal, StoreVal, BinOpRes // StoreVal = sc StoreVal, 0(Ptr) // beq StoreVal, zero, loopMBB - BuildMI(loopMBB, DL, TII->get(Mips::AND), StoreVal) - .addReg(OldVal).addReg(Mask2); - BuildMI(loopMBB, DL, TII->get(Mips::OR), StoreVal) - .addReg(StoreVal).addReg(BinOpRes); - BuildMI(loopMBB, DL, TII->get(SC), StoreVal) - .addReg(StoreVal).addReg(Ptr).addImm(0); - BuildMI(loopMBB, DL, TII->get(BEQ)) - .addReg(StoreVal).addReg(Mips::ZERO).addMBB(loopMBB); + if (NoMovnInstr) { + BuildMI(loop2MBB, DL, TII->get(Mips::AND), StoreVal) + .addReg(OldVal) + .addReg(Mask2); + BuildMI(loop2MBB, DL, TII->get(Mips::OR), StoreVal) + .addReg(StoreVal) + .addReg(BinOpRes); + BuildMI(loop2MBB, DL, TII->get(SC), StoreVal) + .addReg(StoreVal) + .addReg(Ptr) + .addImm(0); + BuildMI(loop2MBB, DL, TII->get(BEQ)) + .addReg(StoreVal) + .addReg(Mips::ZERO) + .addMBB(loopMBB); + } else { + BuildMI(loopMBB, DL, TII->get(Mips::AND), StoreVal) + .addReg(OldVal) + .addReg(Mask2); + BuildMI(loopMBB, DL, TII->get(Mips::OR), StoreVal) + .addReg(StoreVal) + .addReg(BinOpRes); + BuildMI(loopMBB, DL, TII->get(SC), StoreVal) + .addReg(StoreVal) + .addReg(Ptr) + .addImm(0); + BuildMI(loopMBB, DL, TII->get(BEQ)) + .addReg(StoreVal) + .addReg(Mips::ZERO) + .addMBB(loopMBB); + } // sinkMBB: // and maskedoldval1,oldval,mask @@ -601,6 +692,10 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( LivePhysRegs LiveRegs; computeAndAddLiveIns(LiveRegs, *loopMBB); + if (NoMovnInstr) { + computeAndAddLiveIns(LiveRegs, *loop1MBB); + computeAndAddLiveIns(LiveRegs, *loop2MBB); + } computeAndAddLiveIns(LiveRegs, *sinkMBB); computeAndAddLiveIns(LiveRegs, *exitMBB); @@ -747,20 +842,41 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB, llvm_unreachable("Unknown pseudo atomic!"); } + bool NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4() && !STI->hasMips32(); const BasicBlock *LLVM_BB = BB.getBasicBlock(); MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *loop1MBB; + MachineBasicBlock *loop2MBB; + if (NoMovnInstr) { + loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB); + loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB); + } MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); MachineFunction::iterator It = ++BB.getIterator(); MF->insert(It, loopMBB); + if (NoMovnInstr) { + MF->insert(It, loop1MBB); + MF->insert(It, loop2MBB); + } MF->insert(It, exitMBB); exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end()); exitMBB->transferSuccessorsAndUpdatePHIs(&BB); BB.addSuccessor(loopMBB, BranchProbability::getOne()); - loopMBB->addSuccessor(exitMBB); - loopMBB->addSuccessor(loopMBB); + if (NoMovnInstr) { + loopMBB->addSuccessor(loop1MBB); + loopMBB->addSuccessor(loop2MBB); + } else { + loopMBB->addSuccessor(exitMBB); + loopMBB->addSuccessor(loopMBB); + } loopMBB->normalizeSuccProbs(); + if (NoMovnInstr) { + loop1MBB->addSuccessor(loop2MBB); + loop2MBB->addSuccessor(loopMBB); + loop2MBB->addSuccessor(exitMBB, BranchProbability::getOne()); + } BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0); assert((OldVal != Ptr) && "Clobbered the wrong ptr reg!"); @@ -803,7 +919,7 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB, BuildMI(loopMBB, DL, TII->get(OR), Scratch) .addReg(Scratch) .addReg(Scratch2); - } else { + } else if (STI->hasMips4() || STI->hasMips32()) { // max: move Scratch, OldVal // movn Scratch, Incr, Scratch2, Scratch // min: move Scratch, OldVal @@ -815,6 +931,38 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB, .addReg(Incr) .addReg(Scratch2) .addReg(Scratch); + } else { + // if min: + // loopMBB: move Scratch, OldVal + // beq Scratch2_32, 0, loop1MBB + // j loop2MBB + // loop1MBB: move Scratch, Incr + // loop2MBB: sc $2, 0($4) + // beqz $2, $BB0_1 + // nop + // + // if max: + // loopMBB: move Scratch, Incr + // beq Scratch2_32, 0, loop1MBB + // j loop2MBB + // loop1MBB: move Scratch, OldVal + // loop2MBB: sc $2, 0($4) + // beqz $2, $BB0_1 + // nop + if (IsMin) { + BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(OldVal).addReg(ZERO); + BuildMI(loop1MBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO); + } else { + BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO); + BuildMI(loop1MBB, DL, TII->get(OR), Scratch) + .addReg(OldVal) + .addReg(ZERO); + } + BuildMI(loopMBB, DL, TII->get(BEQ)) + .addReg(Scratch2_32) + .addReg(ZERO) + .addMBB(loop1MBB); + BuildMI(loopMBB, DL, TII->get(Mips::B)).addMBB(loop2MBB); } } else if (Opcode) { @@ -830,20 +978,35 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB, BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO); } - BuildMI(loopMBB, DL, TII->get(SC), Scratch) - .addReg(Scratch) - .addReg(Ptr) - .addImm(0); - BuildMI(loopMBB, DL, TII->get(BEQ)) - .addReg(Scratch) - .addReg(ZERO) - .addMBB(loopMBB); + if (NoMovnInstr) { + BuildMI(loop2MBB, DL, TII->get(SC), Scratch) + .addReg(Scratch) + .addReg(Ptr) + .addImm(0); + BuildMI(loop2MBB, DL, TII->get(BEQ)) + .addReg(Scratch) + .addReg(ZERO) + .addMBB(loopMBB); + } else { + BuildMI(loopMBB, DL, TII->get(SC), Scratch) + .addReg(Scratch) + .addReg(Ptr) + .addImm(0); + BuildMI(loopMBB, DL, TII->get(BEQ)) + .addReg(Scratch) + .addReg(ZERO) + .addMBB(loopMBB); + } NMBBI = BB.end(); I->eraseFromParent(); LivePhysRegs LiveRegs; computeAndAddLiveIns(LiveRegs, *loopMBB); + if (!STI->hasMips4() && !STI->hasMips32()) { + computeAndAddLiveIns(LiveRegs, *loop1MBB); + computeAndAddLiveIns(LiveRegs, *loop2MBB); + } computeAndAddLiveIns(LiveRegs, *exitMBB); return true; diff --git a/llvm/test/CodeGen/Mips/atomic-min-max.ll b/llvm/test/CodeGen/Mips/atomic-min-max.ll index 85bf6d02c7d8f..8320224680ff8 100644 --- a/llvm/test/CodeGen/Mips/atomic-min-max.ll +++ b/llvm/test/CodeGen/Mips/atomic-min-max.ll @@ -3,6 +3,7 @@ ; RUN: llc -mtriple=mips-elf -O0 -mcpu=mips32r6 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=MIPSR6 ; RUN: llc -mtriple=mips-elf -O0 -mcpu=mips32r2 -mattr=+micromips -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=MM ; RUN: llc -mtriple=mips-elf -O0 -mcpu=mips32r6 -mattr=+micromips -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=MMR6 +; RUN: llc -mtriple=mipsel-elf -O0 -mcpu=mips2 %s -o - | FileCheck %s --check-prefix=MIPS2 ; RUN: llc -mtriple=mipsel-elf -O0 -mcpu=mips32 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=MIPS32 ; RUN: llc -mtriple=mipsel-elf -O0 -mcpu=mips32r2 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=MIPSEL ; RUN: llc -mtriple=mipsel-elf -O0 -mcpu=mips32r6 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=MIPSELR6 @@ -31,6 +32,33 @@ define i32 @test_max_32(ptr nocapture %ptr, i32 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_max_32: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: sync +; MIPS2-NEXT: $BB0_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($4) +; MIPS2-NEXT: slt $3, $2, $5 +; MIPS2-NEXT: move $1, $5 +; MIPS2-NEXT: beqz $3, $BB0_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB0_1 Depth=1 +; MIPS2-NEXT: b $BB0_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB0_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB0_1 Depth=1 +; MIPS2-NEXT: move $1, $2 +; MIPS2-NEXT: $BB0_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB0_1 Depth=1 +; MIPS2-NEXT: sc $1, 0($4) +; MIPS2-NEXT: beqz $1, $BB0_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: sync +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_max_32: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: sync @@ -251,6 +279,33 @@ define i32 @test_min_32(ptr nocapture %ptr, i32 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_min_32: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: sync +; MIPS2-NEXT: $BB1_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($4) +; MIPS2-NEXT: slt $3, $2, $5 +; MIPS2-NEXT: move $1, $2 +; MIPS2-NEXT: beqz $3, $BB1_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB1_1 Depth=1 +; MIPS2-NEXT: b $BB1_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB1_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB1_1 Depth=1 +; MIPS2-NEXT: move $1, $5 +; MIPS2-NEXT: $BB1_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB1_1 Depth=1 +; MIPS2-NEXT: sc $1, 0($4) +; MIPS2-NEXT: beqz $1, $BB1_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: sync +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_min_32: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: sync @@ -471,6 +526,33 @@ define i32 @test_umax_32(ptr nocapture %ptr, i32 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_umax_32: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: sync +; MIPS2-NEXT: $BB2_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($4) +; MIPS2-NEXT: sltu $3, $2, $5 +; MIPS2-NEXT: move $1, $5 +; MIPS2-NEXT: beqz $3, $BB2_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB2_1 Depth=1 +; MIPS2-NEXT: b $BB2_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB2_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB2_1 Depth=1 +; MIPS2-NEXT: move $1, $2 +; MIPS2-NEXT: $BB2_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB2_1 Depth=1 +; MIPS2-NEXT: sc $1, 0($4) +; MIPS2-NEXT: beqz $1, $BB2_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: sync +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_umax_32: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: sync @@ -691,6 +773,33 @@ define i32 @test_umin_32(ptr nocapture %ptr, i32 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_umin_32: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: sync +; MIPS2-NEXT: $BB3_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($4) +; MIPS2-NEXT: sltu $3, $2, $5 +; MIPS2-NEXT: move $1, $2 +; MIPS2-NEXT: beqz $3, $BB3_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB3_1 Depth=1 +; MIPS2-NEXT: b $BB3_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB3_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB3_1 Depth=1 +; MIPS2-NEXT: move $1, $5 +; MIPS2-NEXT: $BB3_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB3_1 Depth=1 +; MIPS2-NEXT: sc $1, 0($4) +; MIPS2-NEXT: beqz $1, $BB3_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: sync +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_umin_32: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: sync @@ -936,6 +1045,58 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_max_16: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: addiu $sp, $sp, -8 +; MIPS2-NEXT: .cfi_def_cfa_offset 8 +; MIPS2-NEXT: # kill: def $at killed $a1 +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $1, $zero, -4 +; MIPS2-NEXT: and $6, $4, $1 +; MIPS2-NEXT: andi $1, $4, 3 +; MIPS2-NEXT: sll $10, $1, 3 +; MIPS2-NEXT: ori $1, $zero, 65535 +; MIPS2-NEXT: sllv $8, $1, $10 +; MIPS2-NEXT: nor $9, $zero, $8 +; MIPS2-NEXT: sllv $7, $5, $10 +; MIPS2-NEXT: $BB4_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($6) +; MIPS2-NEXT: srav $4, $2, $10 +; MIPS2-NEXT: sll $4, $4, 16 +; MIPS2-NEXT: sra $4, $4, 16 +; MIPS2-NEXT: or $1, $zero, $4 +; MIPS2-NEXT: sllv $4, $4, $10 +; MIPS2-NEXT: slt $5, $4, $7 +; MIPS2-NEXT: move $3, $7 +; MIPS2-NEXT: beqz $5, $BB4_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB4_1 Depth=1 +; MIPS2-NEXT: b $BB4_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB4_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB4_1 Depth=1 +; MIPS2-NEXT: move $3, $4 +; MIPS2-NEXT: $BB4_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB4_1 Depth=1 +; MIPS2-NEXT: and $3, $3, $8 +; MIPS2-NEXT: and $4, $2, $9 +; MIPS2-NEXT: or $4, $4, $3 +; MIPS2-NEXT: sc $4, 0($6) +; MIPS2-NEXT: beqz $4, $BB4_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: .insn +; MIPS2-NEXT: $BB4_6: # %entry +; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill +; MIPS2-NEXT: # %bb.7: # %entry +; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $sp, $sp, 8 +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_max_16: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: addiu $sp, $sp, -8 @@ -1476,6 +1637,58 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_min_16: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: addiu $sp, $sp, -8 +; MIPS2-NEXT: .cfi_def_cfa_offset 8 +; MIPS2-NEXT: # kill: def $at killed $a1 +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $1, $zero, -4 +; MIPS2-NEXT: and $6, $4, $1 +; MIPS2-NEXT: andi $1, $4, 3 +; MIPS2-NEXT: sll $10, $1, 3 +; MIPS2-NEXT: ori $1, $zero, 65535 +; MIPS2-NEXT: sllv $8, $1, $10 +; MIPS2-NEXT: nor $9, $zero, $8 +; MIPS2-NEXT: sllv $7, $5, $10 +; MIPS2-NEXT: $BB5_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($6) +; MIPS2-NEXT: srav $4, $2, $10 +; MIPS2-NEXT: sll $4, $4, 16 +; MIPS2-NEXT: sra $4, $4, 16 +; MIPS2-NEXT: or $1, $zero, $4 +; MIPS2-NEXT: sllv $4, $4, $10 +; MIPS2-NEXT: slt $5, $4, $7 +; MIPS2-NEXT: move $3, $4 +; MIPS2-NEXT: beqz $5, $BB5_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB5_1 Depth=1 +; MIPS2-NEXT: b $BB5_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB5_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB5_1 Depth=1 +; MIPS2-NEXT: move $3, $7 +; MIPS2-NEXT: $BB5_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB5_1 Depth=1 +; MIPS2-NEXT: and $3, $3, $8 +; MIPS2-NEXT: and $4, $2, $9 +; MIPS2-NEXT: or $4, $4, $3 +; MIPS2-NEXT: sc $4, 0($6) +; MIPS2-NEXT: beqz $4, $BB5_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: .insn +; MIPS2-NEXT: $BB5_6: # %entry +; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill +; MIPS2-NEXT: # %bb.7: # %entry +; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $sp, $sp, 8 +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_min_16: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: addiu $sp, $sp, -8 @@ -2015,6 +2228,57 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_umax_16: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: addiu $sp, $sp, -8 +; MIPS2-NEXT: .cfi_def_cfa_offset 8 +; MIPS2-NEXT: # kill: def $at killed $a1 +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $1, $zero, -4 +; MIPS2-NEXT: and $6, $4, $1 +; MIPS2-NEXT: andi $1, $4, 3 +; MIPS2-NEXT: sll $10, $1, 3 +; MIPS2-NEXT: ori $1, $zero, 65535 +; MIPS2-NEXT: sllv $8, $1, $10 +; MIPS2-NEXT: nor $9, $zero, $8 +; MIPS2-NEXT: sllv $7, $5, $10 +; MIPS2-NEXT: $BB6_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($6) +; MIPS2-NEXT: srav $4, $2, $10 +; MIPS2-NEXT: andi $4, $4, 65535 +; MIPS2-NEXT: or $1, $zero, $4 +; MIPS2-NEXT: sllv $4, $4, $10 +; MIPS2-NEXT: sltu $5, $4, $7 +; MIPS2-NEXT: move $3, $7 +; MIPS2-NEXT: beqz $5, $BB6_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB6_1 Depth=1 +; MIPS2-NEXT: b $BB6_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB6_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB6_1 Depth=1 +; MIPS2-NEXT: move $3, $4 +; MIPS2-NEXT: $BB6_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB6_1 Depth=1 +; MIPS2-NEXT: and $3, $3, $8 +; MIPS2-NEXT: and $4, $2, $9 +; MIPS2-NEXT: or $4, $4, $3 +; MIPS2-NEXT: sc $4, 0($6) +; MIPS2-NEXT: beqz $4, $BB6_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: .insn +; MIPS2-NEXT: $BB6_6: # %entry +; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill +; MIPS2-NEXT: # %bb.7: # %entry +; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $sp, $sp, 8 +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_umax_16: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: addiu $sp, $sp, -8 @@ -2553,6 +2817,57 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_umin_16: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: addiu $sp, $sp, -8 +; MIPS2-NEXT: .cfi_def_cfa_offset 8 +; MIPS2-NEXT: # kill: def $at killed $a1 +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $1, $zero, -4 +; MIPS2-NEXT: and $6, $4, $1 +; MIPS2-NEXT: andi $1, $4, 3 +; MIPS2-NEXT: sll $10, $1, 3 +; MIPS2-NEXT: ori $1, $zero, 65535 +; MIPS2-NEXT: sllv $8, $1, $10 +; MIPS2-NEXT: nor $9, $zero, $8 +; MIPS2-NEXT: sllv $7, $5, $10 +; MIPS2-NEXT: $BB7_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($6) +; MIPS2-NEXT: srav $4, $2, $10 +; MIPS2-NEXT: andi $4, $4, 65535 +; MIPS2-NEXT: or $1, $zero, $4 +; MIPS2-NEXT: sllv $4, $4, $10 +; MIPS2-NEXT: sltu $5, $4, $7 +; MIPS2-NEXT: move $3, $4 +; MIPS2-NEXT: beqz $5, $BB7_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB7_1 Depth=1 +; MIPS2-NEXT: b $BB7_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB7_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB7_1 Depth=1 +; MIPS2-NEXT: move $3, $7 +; MIPS2-NEXT: $BB7_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB7_1 Depth=1 +; MIPS2-NEXT: and $3, $3, $8 +; MIPS2-NEXT: and $4, $2, $9 +; MIPS2-NEXT: or $4, $4, $3 +; MIPS2-NEXT: sc $4, 0($6) +; MIPS2-NEXT: beqz $4, $BB7_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: .insn +; MIPS2-NEXT: $BB7_6: # %entry +; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill +; MIPS2-NEXT: # %bb.7: # %entry +; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $sp, $sp, 8 +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_umin_16: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: addiu $sp, $sp, -8 @@ -3092,6 +3407,58 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_max_8: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: addiu $sp, $sp, -8 +; MIPS2-NEXT: .cfi_def_cfa_offset 8 +; MIPS2-NEXT: # kill: def $at killed $a1 +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $1, $zero, -4 +; MIPS2-NEXT: and $6, $4, $1 +; MIPS2-NEXT: andi $1, $4, 3 +; MIPS2-NEXT: sll $10, $1, 3 +; MIPS2-NEXT: ori $1, $zero, 255 +; MIPS2-NEXT: sllv $8, $1, $10 +; MIPS2-NEXT: nor $9, $zero, $8 +; MIPS2-NEXT: sllv $7, $5, $10 +; MIPS2-NEXT: $BB8_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($6) +; MIPS2-NEXT: srav $4, $2, $10 +; MIPS2-NEXT: sll $4, $4, 24 +; MIPS2-NEXT: sra $4, $4, 24 +; MIPS2-NEXT: or $1, $zero, $4 +; MIPS2-NEXT: sllv $4, $4, $10 +; MIPS2-NEXT: slt $5, $4, $7 +; MIPS2-NEXT: move $3, $7 +; MIPS2-NEXT: beqz $5, $BB8_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB8_1 Depth=1 +; MIPS2-NEXT: b $BB8_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB8_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB8_1 Depth=1 +; MIPS2-NEXT: move $3, $4 +; MIPS2-NEXT: $BB8_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB8_1 Depth=1 +; MIPS2-NEXT: and $3, $3, $8 +; MIPS2-NEXT: and $4, $2, $9 +; MIPS2-NEXT: or $4, $4, $3 +; MIPS2-NEXT: sc $4, 0($6) +; MIPS2-NEXT: beqz $4, $BB8_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: .insn +; MIPS2-NEXT: $BB8_6: # %entry +; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill +; MIPS2-NEXT: # %bb.7: # %entry +; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $sp, $sp, 8 +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_max_8: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: addiu $sp, $sp, -8 @@ -3631,6 +3998,58 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_min_8: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: addiu $sp, $sp, -8 +; MIPS2-NEXT: .cfi_def_cfa_offset 8 +; MIPS2-NEXT: # kill: def $at killed $a1 +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $1, $zero, -4 +; MIPS2-NEXT: and $6, $4, $1 +; MIPS2-NEXT: andi $1, $4, 3 +; MIPS2-NEXT: sll $10, $1, 3 +; MIPS2-NEXT: ori $1, $zero, 255 +; MIPS2-NEXT: sllv $8, $1, $10 +; MIPS2-NEXT: nor $9, $zero, $8 +; MIPS2-NEXT: sllv $7, $5, $10 +; MIPS2-NEXT: $BB9_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($6) +; MIPS2-NEXT: srav $4, $2, $10 +; MIPS2-NEXT: sll $4, $4, 24 +; MIPS2-NEXT: sra $4, $4, 24 +; MIPS2-NEXT: or $1, $zero, $4 +; MIPS2-NEXT: sllv $4, $4, $10 +; MIPS2-NEXT: slt $5, $4, $7 +; MIPS2-NEXT: move $3, $4 +; MIPS2-NEXT: beqz $5, $BB9_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB9_1 Depth=1 +; MIPS2-NEXT: b $BB9_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB9_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB9_1 Depth=1 +; MIPS2-NEXT: move $3, $7 +; MIPS2-NEXT: $BB9_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB9_1 Depth=1 +; MIPS2-NEXT: and $3, $3, $8 +; MIPS2-NEXT: and $4, $2, $9 +; MIPS2-NEXT: or $4, $4, $3 +; MIPS2-NEXT: sc $4, 0($6) +; MIPS2-NEXT: beqz $4, $BB9_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: .insn +; MIPS2-NEXT: $BB9_6: # %entry +; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill +; MIPS2-NEXT: # %bb.7: # %entry +; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $sp, $sp, 8 +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_min_8: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: addiu $sp, $sp, -8 @@ -4170,6 +4589,57 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_umax_8: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: addiu $sp, $sp, -8 +; MIPS2-NEXT: .cfi_def_cfa_offset 8 +; MIPS2-NEXT: # kill: def $at killed $a1 +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $1, $zero, -4 +; MIPS2-NEXT: and $6, $4, $1 +; MIPS2-NEXT: andi $1, $4, 3 +; MIPS2-NEXT: sll $10, $1, 3 +; MIPS2-NEXT: ori $1, $zero, 255 +; MIPS2-NEXT: sllv $8, $1, $10 +; MIPS2-NEXT: nor $9, $zero, $8 +; MIPS2-NEXT: sllv $7, $5, $10 +; MIPS2-NEXT: $BB10_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($6) +; MIPS2-NEXT: srav $4, $2, $10 +; MIPS2-NEXT: andi $4, $4, 255 +; MIPS2-NEXT: or $1, $zero, $4 +; MIPS2-NEXT: sllv $4, $4, $10 +; MIPS2-NEXT: sltu $5, $4, $7 +; MIPS2-NEXT: move $3, $7 +; MIPS2-NEXT: beqz $5, $BB10_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB10_1 Depth=1 +; MIPS2-NEXT: b $BB10_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB10_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB10_1 Depth=1 +; MIPS2-NEXT: move $3, $4 +; MIPS2-NEXT: $BB10_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB10_1 Depth=1 +; MIPS2-NEXT: and $3, $3, $8 +; MIPS2-NEXT: and $4, $2, $9 +; MIPS2-NEXT: or $4, $4, $3 +; MIPS2-NEXT: sc $4, 0($6) +; MIPS2-NEXT: beqz $4, $BB10_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: .insn +; MIPS2-NEXT: $BB10_6: # %entry +; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill +; MIPS2-NEXT: # %bb.7: # %entry +; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $sp, $sp, 8 +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_umax_8: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: addiu $sp, $sp, -8 @@ -4708,6 +5178,57 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: jr $ra ; MIPS-NEXT: nop ; +; MIPS2-LABEL: test_umin_8: +; MIPS2: # %bb.0: # %entry +; MIPS2-NEXT: addiu $sp, $sp, -8 +; MIPS2-NEXT: .cfi_def_cfa_offset 8 +; MIPS2-NEXT: # kill: def $at killed $a1 +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $1, $zero, -4 +; MIPS2-NEXT: and $6, $4, $1 +; MIPS2-NEXT: andi $1, $4, 3 +; MIPS2-NEXT: sll $10, $1, 3 +; MIPS2-NEXT: ori $1, $zero, 255 +; MIPS2-NEXT: sllv $8, $1, $10 +; MIPS2-NEXT: nor $9, $zero, $8 +; MIPS2-NEXT: sllv $7, $5, $10 +; MIPS2-NEXT: $BB11_1: # %entry +; MIPS2-NEXT: # =>This Inner Loop Header: Depth=1 +; MIPS2-NEXT: ll $2, 0($6) +; MIPS2-NEXT: srav $4, $2, $10 +; MIPS2-NEXT: andi $4, $4, 255 +; MIPS2-NEXT: or $1, $zero, $4 +; MIPS2-NEXT: sllv $4, $4, $10 +; MIPS2-NEXT: sltu $5, $4, $7 +; MIPS2-NEXT: move $3, $4 +; MIPS2-NEXT: beqz $5, $BB11_3 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.2: # %entry +; MIPS2-NEXT: # in Loop: Header=BB11_1 Depth=1 +; MIPS2-NEXT: b $BB11_4 +; MIPS2-NEXT: nop +; MIPS2-NEXT: $BB11_3: # %entry +; MIPS2-NEXT: # in Loop: Header=BB11_1 Depth=1 +; MIPS2-NEXT: move $3, $7 +; MIPS2-NEXT: $BB11_4: # %entry +; MIPS2-NEXT: # in Loop: Header=BB11_1 Depth=1 +; MIPS2-NEXT: and $3, $3, $8 +; MIPS2-NEXT: and $4, $2, $9 +; MIPS2-NEXT: or $4, $4, $3 +; MIPS2-NEXT: sc $4, 0($6) +; MIPS2-NEXT: beqz $4, $BB11_1 +; MIPS2-NEXT: nop +; MIPS2-NEXT: # %bb.5: # %entry +; MIPS2-NEXT: .insn +; MIPS2-NEXT: $BB11_6: # %entry +; MIPS2-NEXT: sw $1, 4($sp) # 4-byte Folded Spill +; MIPS2-NEXT: # %bb.7: # %entry +; MIPS2-NEXT: lw $2, 4($sp) # 4-byte Folded Reload +; MIPS2-NEXT: sync +; MIPS2-NEXT: addiu $sp, $sp, 8 +; MIPS2-NEXT: jr $ra +; MIPS2-NEXT: nop +; ; MIPSR6-LABEL: test_umin_8: ; MIPSR6: # %bb.0: # %entry ; MIPSR6-NEXT: addiu $sp, $sp, -8